Что происходит с QSocketNotifier, когда дескриптор файла становится плохим? - PullRequest
0 голосов
/ 16 октября 2018

Предполагая, что у меня есть QSocketNotifier, который построен на основе допустимого файлового дескриптора (на самом деле это устройство джойстика - /dev/input/js0).Я подключаю QSocketNotifier::activated с соответствующим обработчиком.Когда файл исчезает (аппаратное обеспечение отключено) - чего мне ожидать?

Как я вижу, ::activated выдает повторно с тем же параметром сокета, но после вызова read() внутри обработчика происходит errno == ENODEV.Могу ли я ожидать, что ::activated будет всегда , испускаемым после того, как дескриптор выходит из строя (и, следовательно, перехватывает событие отключения), или фактическое поведение QSocketNotifier не определено?

1 Ответ

0 голосов
/ 16 октября 2018

Я не могу говорить о поведении /dev/input/js0, в частности, так как я никогда не использовал это устройство, но общее поведение для сокета / дескриптора файла, удаленное соединение которого было закрыто, было бы возвращать как готовыйfor-read, а затем, когда приложение пытается вызвать recv() (или read()) для файлового дескриптора, любой из этих вызовов вернет 0 (он же EOF), чтобы указать, что удаленное устройство закрыло соединение.

Предположительно, это (или что-то подобное) происходит и при использовании QSocketNotifier, то есть внутренний код Qt уведомит QSocketNotifier, что дескриптор файла теперь готов для чтения, и QSocketNotifier ответитиспуская activated(int) Qt-сигнал.Поэтому я думаю, что ваш шаблон использования хорош.

(что будет плохим / неопределенным поведением, если вы (или кто-то еще) вызвали close() в дескрипторе файла без предварительного отключения илиуничтожение любых QSocketNotifier объектов, которые наблюдали за этим файловым дескриптором. Это было бы плохо, потому что у QSocketNotifier объектов не было бы возможности узнать, что файловый дескриптор был закрыт, и поэтому они продолжали бы пытаться использовать его- возможно, они получат ошибки типа EBADFS, когда они это сделают, но есть также вероятность того, что какой-то другой поток в вашем процессе вскоре создаст новый файловый дескриптор для какой-то несвязанной цели, и случайно он закончится сто же самое int-значение, которое было ранее close() 'd, и тогда вы действительно весело провели бы время, отлаживая странное поведение, которое получилось:))

...