@@ -51,7 +51,8 @@ typedef struct dispatch_muxnote_s {
51
51
int dmn_ident ;
52
52
uint32_t dmn_events ;
53
53
int16_t dmn_filter ;
54
- bool dmn_socket_listener ;
54
+ bool dmn_skip_outq_ioctl ;
55
+ bool dmn_skip_inq_ioctl ;
55
56
} * dispatch_muxnote_t ;
56
57
57
58
typedef struct dispatch_epoll_timeout_s {
@@ -143,7 +144,7 @@ _dispatch_muxnote_create(dispatch_unote_t du, uint32_t events)
143
144
struct stat sb ;
144
145
int fd = du ._du -> du_ident ;
145
146
int16_t filter = du ._du -> du_filter ;
146
- bool socket_listener = false;
147
+ bool skip_outq_ioctl = false, skip_inq_ioctl = false;
147
148
sigset_t sigmask ;
148
149
149
150
switch (filter ) {
@@ -173,11 +174,15 @@ _dispatch_muxnote_create(dispatch_unote_t du, uint32_t events)
173
174
if (fd < 0 ) {
174
175
return NULL ;
175
176
}
177
+ // Linux doesn't support output queue size ioctls for regular files
178
+ skip_outq_ioctl = true;
176
179
} else if (S_ISSOCK (sb .st_mode )) {
177
180
socklen_t vlen = sizeof (int );
178
181
int v ;
182
+ // Linux doesn't support saying how many clients are ready to be
183
+ // accept()ed for sockets
179
184
if (getsockopt (fd , SOL_SOCKET , SO_ACCEPTCONN , & v , & vlen ) == 0 ) {
180
- socket_listener = (bool )v ;
185
+ skip_inq_ioctl = (bool )v ;
181
186
}
182
187
}
183
188
break ;
@@ -193,7 +198,8 @@ _dispatch_muxnote_create(dispatch_unote_t du, uint32_t events)
193
198
dmn -> dmn_ident = du ._du -> du_ident ;
194
199
dmn -> dmn_filter = filter ;
195
200
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 ;
197
203
return dmn ;
198
204
}
199
205
@@ -480,16 +486,27 @@ _dispatch_event_merge_signal(dispatch_muxnote_t dmn)
480
486
static uintptr_t
481
487
_dispatch_get_buffer_size (dispatch_muxnote_t dmn , bool writer )
482
488
{
483
- unsigned long op = writer ? SIOCOUTQ : SIOCINQ ;
484
489
int n ;
485
490
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 ) {
489
492
return 1 ;
490
493
}
491
494
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
+ }
493
510
return 1 ;
494
511
}
495
512
return (uintptr_t )n ;
0 commit comments