Dmitry Vornychev
Dmitry Vornychev

Reputation: 615

What is happened with QSocketNotifier when file descriptor becomes bad?

Assuming I have QSocketNotifier that is constructed against valid file descriptor (it's actually joystick device - /dev/input/js0). I connect QSocketNotifier::activated with corresponding handler. When file disappears (hardware is disconnected) - what should I expect?

As I can see, ::activated emits repeatedely with the same socket parameter, but there is errno == ENODEV after read() call inside handler. May I expect that ::activated would be always emitted after descriptor goes bad (and therefore catch disconnection event) or actual behavior of QSocketNotifier is not defined?

Upvotes: 2

Views: 766

Answers (1)

Jeremy Friesner
Jeremy Friesner

Reputation: 73091

I can't speak to the behavior of /dev/input/js0 in particular since I've never used that device, but the general behavior for a socket/file-descriptor whose remote-connection has closed would be to return as ready-for-read, and then when the application tries to call recv() (or read()) on the file descriptor, either of these calls would return 0 (a.k.a. EOF) to indicate that the remote device has closed the connection.

Presumably this (or something similar) is happens when using QSocketNotifier as well, i.e. Qt's internal code will notify the QSocketNotifier that the file descriptor is now ready-for-read, and the QSocketNotifier will respond by emitting the activated(int) Qt-signal. So I think your use-pattern is good.

(What would be bad/undefined behavior is if you (or somebody else) called close() on the file descriptor without first disabling or destroying any QSocketNotifier objects that were watching that file-descriptor. That would be bad because the QSocketNotifier object(s) would have no way to know that the file descriptor was closed, and so they'd keep trying to use it -- probably they would get EBADFS-type errors when they did so, but there's also a chance that some other thread in your process would create a new file descriptor shortly afterwards for some unrelated purpose, and by chance it would end up with the same int-value as the one that was previously close()'d, and then you'd have a really fun time debugging the odd behavior that resulted :))

Upvotes: 2

Related Questions