@@ -51,7 +51,8 @@ typedef struct dispatch_muxnote_s {
5151 int dmn_ident ;
5252 uint32_t dmn_events ;
5353 int16_t dmn_filter ;
54- bool dmn_socket_listener ;
54+ bool dmn_skip_outq_ioctl ;
55+ bool dmn_skip_inq_ioctl ;
5556} * dispatch_muxnote_t ;
5657
5758typedef struct dispatch_epoll_timeout_s {
@@ -143,7 +144,7 @@ _dispatch_muxnote_create(dispatch_unote_t du, uint32_t events)
143144 struct stat sb ;
144145 int fd = du ._du -> du_ident ;
145146 int16_t filter = du ._du -> du_filter ;
146- bool socket_listener = false;
147+ bool skip_outq_ioctl = false, skip_inq_ioctl = false;
147148 sigset_t sigmask ;
148149
149150 switch (filter ) {
@@ -173,11 +174,15 @@ _dispatch_muxnote_create(dispatch_unote_t du, uint32_t events)
173174 if (fd < 0 ) {
174175 return NULL ;
175176 }
177+ // Linux doesn't support output queue size ioctls for regular files
178+ skip_outq_ioctl = true;
176179 } else if (S_ISSOCK (sb .st_mode )) {
177180 socklen_t vlen = sizeof (int );
178181 int v ;
182+ // Linux doesn't support saying how many clients are ready to be
183+ // accept()ed for sockets
179184 if (getsockopt (fd , SOL_SOCKET , SO_ACCEPTCONN , & v , & vlen ) == 0 ) {
180- socket_listener = (bool )v ;
185+ skip_outq_ioctl = (bool )v ;
181186 }
182187 }
183188 break ;
@@ -193,7 +198,8 @@ _dispatch_muxnote_create(dispatch_unote_t du, uint32_t events)
193198 dmn -> dmn_ident = du ._du -> du_ident ;
194199 dmn -> dmn_filter = filter ;
195200 dmn -> dmn_events = events ;
196- dmn -> dmn_socket_listener = socket_listener ;
201+ dmn -> dmn_skip_outq_ioctl = skip_outq_ioctl ;
202+ dmn -> dmn_skip_inq_ioctl = skip_inq_ioctl ;
197203 return dmn ;
198204}
199205
@@ -480,16 +486,27 @@ _dispatch_event_merge_signal(dispatch_muxnote_t dmn)
480486static uintptr_t
481487_dispatch_get_buffer_size (dispatch_muxnote_t dmn , bool writer )
482488{
483- unsigned long op = writer ? SIOCOUTQ : SIOCINQ ;
484489 int n ;
485490
486- if (!writer && dmn -> dmn_socket_listener ) {
487- // Linux doesn't support saying how many clients are ready to be
488- // accept()ed
491+ if (writer ? dmn -> dmn_skip_outq_ioctl : dmn -> dmn_skip_inq_ioctl ) {
489492 return 1 ;
490493 }
491494
492- if (dispatch_assume_zero (ioctl (dmn -> dmn_ident , op , & n ))) {
495+ if (ioctl (dmn -> dmn_ident , writer ? SIOCOUTQ : SIOCINQ , & n ) != 0 ) {
496+ switch (errno ) {
497+ case EINVAL :
498+ // this file descriptor actually doesn't support the buffer
499+ // size ioctl, remember that for next time to avoid the syscall.
500+ break ;
501+ default :
502+ dispatch_assume_zero (errno );
503+ break ;
504+ }
505+ if (writer ) {
506+ dmn -> dmn_skip_outq_ioctl = true;
507+ } else {
508+ dmn -> dmn_skip_inq_ioctl = true;
509+ }
493510 return 1 ;
494511 }
495512 return (uintptr_t )n ;
0 commit comments