@@ -53,6 +53,10 @@ struct uv__stream_select_s {
5353 int fake_fd ;
5454 int int_fd ;
5555 int fd ;
56+ fd_set * sread ;
57+ size_t sread_sz ;
58+ fd_set * swrite ;
59+ size_t swrite_sz ;
5660};
5761#endif /* defined(__APPLE__) */
5862
@@ -131,8 +135,6 @@ static void uv__stream_osx_select(void* arg) {
131135 uv_stream_t * stream ;
132136 uv__stream_select_t * s ;
133137 char buf [1024 ];
134- fd_set sread ;
135- fd_set swrite ;
136138 int events ;
137139 int fd ;
138140 int r ;
@@ -153,17 +155,17 @@ static void uv__stream_osx_select(void* arg) {
153155 break ;
154156
155157 /* Watch fd using select(2) */
156- FD_ZERO ( & sread );
157- FD_ZERO ( & swrite );
158+ memset ( s -> sread , 0 , s -> sread_sz );
159+ memset ( s -> swrite , 0 , s -> swrite_sz );
158160
159161 if (uv_is_readable (stream ))
160- FD_SET (fd , & sread );
162+ FD_SET (fd , s -> sread );
161163 if (uv_is_writable (stream ))
162- FD_SET (fd , & swrite );
163- FD_SET (s -> int_fd , & sread );
164+ FD_SET (fd , s -> swrite );
165+ FD_SET (s -> int_fd , s -> sread );
164166
165167 /* Wait indefinitely for fd events */
166- r = select (max_fd + 1 , & sread , & swrite , NULL , NULL );
168+ r = select (max_fd + 1 , s -> sread , s -> swrite , NULL , NULL );
167169 if (r == -1 ) {
168170 if (errno == EINTR )
169171 continue ;
@@ -177,7 +179,7 @@ static void uv__stream_osx_select(void* arg) {
177179 continue ;
178180
179181 /* Empty socketpair's buffer in case of interruption */
180- if (FD_ISSET (s -> int_fd , & sread ))
182+ if (FD_ISSET (s -> int_fd , s -> sread ))
181183 while (1 ) {
182184 r = read (s -> int_fd , buf , sizeof (buf ));
183185
@@ -198,12 +200,12 @@ static void uv__stream_osx_select(void* arg) {
198200
199201 /* Handle events */
200202 events = 0 ;
201- if (FD_ISSET (fd , & sread ))
203+ if (FD_ISSET (fd , s -> sread ))
202204 events |= UV__POLLIN ;
203- if (FD_ISSET (fd , & swrite ))
205+ if (FD_ISSET (fd , s -> swrite ))
204206 events |= UV__POLLOUT ;
205207
206- assert (events != 0 || FD_ISSET (s -> int_fd , & sread ));
208+ assert (events != 0 || FD_ISSET (s -> int_fd , s -> sread ));
207209 if (events != 0 ) {
208210 ACCESS_ONCE (int , s -> events ) = events ;
209211
@@ -283,6 +285,10 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) {
283285 int ret ;
284286 int kq ;
285287 int old_fd ;
288+ int max_fd ;
289+ size_t sread_sz ;
290+ size_t swrite_sz ;
291+ int err ;
286292
287293 kq = kqueue ();
288294 if (kq == -1 ) {
@@ -306,30 +312,52 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) {
306312 return 0 ;
307313
308314 /* At this point we definitely know that this fd won't work with kqueue */
309- s = malloc (sizeof (* s ));
310- if (s == NULL )
311- return uv__set_artificial_error (stream -> loop , UV_ENOMEM );
315+
316+ /*
317+ * Create fds for io watcher and to interrupt the select() loop.
318+ * NOTE: do it ahead of malloc below to allocate enough space for fd_sets
319+ */
320+ if (socketpair (AF_UNIX , SOCK_STREAM , 0 , fds ))
321+ return uv__set_sys_error (stream -> loop , errno );
322+
323+ max_fd = * fd ;
324+ if (fds [1 ] > max_fd )
325+ max_fd = fds [1 ];
326+
327+ sread_sz = (max_fd + NBBY ) / NBBY ;
328+ swrite_sz = sread_sz ;
329+
330+ s = malloc (sizeof (* s ) + sread_sz + swrite_sz );
331+ if (s == NULL ) {
332+ err = uv__set_artificial_error (stream -> loop , UV_ENOMEM );
333+ goto failed_malloc ;
334+ }
312335
313336 s -> events = 0 ;
314337 s -> fd = * fd ;
338+ s -> sread = (fd_set * ) ((char * ) s + sizeof (* s ));
339+ s -> sread_sz = sread_sz ;
340+ s -> swrite = (fd_set * ) ((char * ) s -> sread + sread_sz );
341+ s -> swrite_sz = swrite_sz ;
315342
316- if (uv_async_init (stream -> loop , & s -> async , uv__stream_osx_select_cb )) {
317- SAVE_ERRNO (free (s ));
318- return uv__set_sys_error (stream -> loop , errno );
319- }
343+ err = uv_async_init (stream -> loop , & s -> async , uv__stream_osx_select_cb );
344+ if (err )
345+ goto failed_async_init ;
320346
321347 s -> async .flags |= UV__HANDLE_INTERNAL ;
322348 uv__handle_unref (& s -> async );
323349
324- if ( uv_sem_init (& s -> close_sem , 0 ))
325- goto fatal1 ;
326-
327- if ( uv_sem_init ( & s -> async_sem , 0 ))
328- goto fatal2 ;
350+ err = uv_sem_init (& s -> close_sem , 0 );
351+ if ( err != 0 ) {
352+ err = uv__set_sys_error ( stream -> loop , UV_UNKNOWN );
353+ goto failed_close_sem_init ;
354+ }
329355
330- /* Create fds for io watcher and to interrupt the select() loop. */
331- if (socketpair (AF_UNIX , SOCK_STREAM , 0 , fds ))
332- goto fatal3 ;
356+ err = uv_sem_init (& s -> async_sem , 0 );
357+ if (err != 0 ) {
358+ err = uv__set_sys_error (stream -> loop , UV_UNKNOWN );
359+ goto failed_async_sem_init ;
360+ }
333361
334362 s -> fake_fd = fds [0 ];
335363 s -> int_fd = fds [1 ];
@@ -339,26 +367,37 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) {
339367 stream -> select = s ;
340368 * fd = s -> fake_fd ;
341369
342- if (uv_thread_create (& s -> thread , uv__stream_osx_select , stream ))
343- goto fatal4 ;
370+ err = uv_thread_create (& s -> thread , uv__stream_osx_select , stream );
371+ if (err != 0 ) {
372+ err = uv__set_sys_error (stream -> loop , UV_UNKNOWN );
373+ goto failed_thread_create ;
374+ }
344375
345376 return 0 ;
346377
347- fatal4 :
378+ failed_thread_create :
348379 s -> stream = NULL ;
349380 stream -> select = NULL ;
350381 * fd = old_fd ;
351- close (s -> fake_fd );
352- close (s -> int_fd );
353- s -> fake_fd = -1 ;
354- s -> int_fd = -1 ;
355- fatal3 :
356382 uv_sem_destroy (& s -> async_sem );
357- fatal2 :
383+
384+ failed_async_sem_init :
358385 uv_sem_destroy (& s -> close_sem );
359- fatal1 :
386+
387+ failed_close_sem_init :
388+ close (fds [0 ]);
389+ close (fds [1 ]);
360390 uv_close ((uv_handle_t * ) & s -> async , uv__stream_osx_cb_close );
361- return uv__set_sys_error (stream -> loop , errno );
391+ return err ;
392+
393+ failed_async_init :
394+ free (s );
395+
396+ failed_malloc :
397+ close (fds [0 ]);
398+ close (fds [1 ]);
399+
400+ return err ;
362401}
363402#endif /* defined(__APPLE__) */
364403
0 commit comments