@@ -213,13 +213,30 @@ CF_INLINE int __CFSocketLastError(void) {
213213}
214214
215215CF_INLINE CFIndex __CFSocketFdGetSize (CFDataRef fdSet ) {
216+ #if TARGET_OS_WIN32
217+ if (CFDataGetLength (fdSet ) == 0 ) {
218+ return 0 ;
219+ }
220+ return FD_SETSIZE ;
221+ #else
216222 return NBBY * CFDataGetLength (fdSet );
223+ #endif
217224}
218225
219226CF_INLINE Boolean __CFSocketFdSet (CFSocketNativeHandle sock , CFMutableDataRef fdSet ) {
220227 /* returns true if a change occurred, false otherwise */
221228 Boolean retval = false;
222229 if (INVALID_SOCKET != sock && 0 <= sock ) {
230+ fd_set * fds ;
231+ #if TARGET_OS_WIN32
232+ if (CFDataGetLength (fdSet ) == 0 ) {
233+ CFDataIncreaseLength (fdSet , sizeof (fd_set ));
234+ fds = (fd_set * )CFDataGetMutableBytePtr (fdSet );
235+ FD_ZERO (fds );
236+ } else {
237+ fds = (fd_set * )CFDataGetMutableBytePtr (fdSet );
238+ }
239+ #else
223240 CFIndex numFds = NBBY * CFDataGetLength (fdSet );
224241 fd_mask * fds_bits ;
225242 if (sock >= numFds ) {
@@ -230,9 +247,11 @@ CF_INLINE Boolean __CFSocketFdSet(CFSocketNativeHandle sock, CFMutableDataRef fd
230247 } else {
231248 fds_bits = (fd_mask * )CFDataGetMutableBytePtr (fdSet );
232249 }
233- if (!FD_ISSET (sock , (fd_set * )fds_bits )) {
250+ fds = (fd_set * )fds_bits ;
251+ #endif
252+ if (!FD_ISSET (sock , fds )) {
234253 retval = true;
235- FD_SET (sock , ( fd_set * ) fds_bits );
254+ FD_SET (sock , fds );
236255 }
237256 }
238257 return retval ;
@@ -416,6 +435,15 @@ CF_INLINE Boolean __CFSocketFdClr(CFSocketNativeHandle sock, CFMutableDataRef fd
416435 /* returns true if a change occurred, false otherwise */
417436 Boolean retval = false;
418437 if (INVALID_SOCKET != sock && 0 <= sock ) {
438+ #if TARGET_OS_WIN32
439+ if (CFDataGetLength (fdSet ) > 0 ) {
440+ fd_set * fds = (fd_set * )CFDataGetMutableBytePtr (fdSet );
441+ if (FD_ISSET (sock , fds )) {
442+ retval = true;
443+ FD_CLR (sock , fds );
444+ }
445+ }
446+ #else
419447 CFIndex numFds = NBBY * CFDataGetLength (fdSet );
420448 fd_mask * fds_bits ;
421449 if (sock < numFds ) {
@@ -425,6 +453,7 @@ CF_INLINE Boolean __CFSocketFdClr(CFSocketNativeHandle sock, CFMutableDataRef fd
425453 FD_CLR (sock , (fd_set * )fds_bits );
426454 }
427455 }
456+ #endif
428457 }
429458 return retval ;
430459}
@@ -1188,6 +1217,27 @@ static void
11881217clearInvalidFileDescriptors (CFMutableDataRef d )
11891218{
11901219 if (d ) {
1220+ #if TARGET_OS_WIN32
1221+ if (CFDataGetLength (d ) == 0 ) {
1222+ return ;
1223+ }
1224+
1225+ fd_set * fds = (fd_set * )CFDataGetMutableBytePtr (d );
1226+ fd_set invalidFds ;
1227+ FD_ZERO (& invalidFds );
1228+ // Gather all invalid sockets into invalidFds set
1229+ for (u_int idx = 0 ; idx < fds -> fd_count ; idx ++ ) {
1230+ SOCKET socket = fds -> fd_array [idx ];
1231+ if (! __CFNativeSocketIsValid (socket )) {
1232+ FD_SET (socket , & invalidFds );
1233+ }
1234+ }
1235+ // Remove invalid sockets from source set
1236+ for (u_int idx = 0 ; idx < invalidFds .fd_count ; idx ++ ) {
1237+ SOCKET socket = invalidFds .fd_array [idx ];
1238+ FD_CLR (socket , fds );
1239+ }
1240+ #else
11911241 SInt32 count = __CFSocketFdGetSize (d );
11921242 fd_set * s = (fd_set * ) CFDataGetMutableBytePtr (d );
11931243 for (SInt32 idx = 0 ; idx < count ; idx ++ ) {
@@ -1196,14 +1246,13 @@ clearInvalidFileDescriptors(CFMutableDataRef d)
11961246 FD_CLR (idx , s );
11971247 }
11981248 }
1249+ #endif
11991250 }
12001251}
12011252
12021253static void
1203- manageSelectError ()
1254+ manageSelectError (SInt32 selectError )
12041255{
1205- SInt32 selectError = __CFSocketLastError ();
1206-
12071256 __CFSOCKETLOG ("socket manager received error %ld from select" , (long )selectError );
12081257
12091258 if (EBADF == selectError ) {
@@ -1263,8 +1312,15 @@ static void *__CFSocketManager(void * arg)
12631312 SInt32 nrfds , maxnrfds , fdentries = 1 ;
12641313 SInt32 rfds , wfds ;
12651314 fd_set * exceptfds = NULL ;
1315+ #if TARGET_OS_WIN32
1316+ fd_set * writefds = (fd_set * )CFAllocatorAllocate (kCFAllocatorSystemDefault , sizeof (fd_set ), 0 );
1317+ fd_set * readfds = (fd_set * )CFAllocatorAllocate (kCFAllocatorSystemDefault , sizeof (fd_set ), 0 );
1318+ FD_ZERO (writefds );
1319+ FD_ZERO (readfds );
1320+ #else
12661321 fd_set * writefds = (fd_set * )CFAllocatorAllocate (kCFAllocatorSystemDefault , fdentries * sizeof (fd_mask ), 0 );
12671322 fd_set * readfds = (fd_set * )CFAllocatorAllocate (kCFAllocatorSystemDefault , fdentries * sizeof (fd_mask ), 0 );
1323+ #endif
12681324 fd_set * tempfds ;
12691325 SInt32 idx , cnt ;
12701326 uint8_t buffer [256 ];
@@ -1290,6 +1346,11 @@ static void *__CFSocketManager(void * arg)
12901346 free (readBuffer );
12911347 free (writeBuffer );
12921348#endif
1349+
1350+ #if TARGET_OS_WIN32
1351+ // This parameter is ignored by `select` from Winsock2 API
1352+ maxnrfds = INT_MAX ;
1353+ #else
12931354 rfds = __CFSocketFdGetSize (__CFReadSocketsFds );
12941355 wfds = __CFSocketFdGetSize (__CFWriteSocketsFds );
12951356 maxnrfds = __CFMax (rfds , wfds );
@@ -1300,6 +1361,7 @@ static void *__CFSocketManager(void * arg)
13001361 }
13011362 memset (writefds , 0 , fdentries * sizeof (fd_mask ));
13021363 memset (readfds , 0 , fdentries * sizeof (fd_mask ));
1364+ #endif
13031365 CFDataGetBytes (__CFWriteSocketsFds , CFRangeMake (0 , CFDataGetLength (__CFWriteSocketsFds )), (UInt8 * )writefds );
13041366 CFDataGetBytes (__CFReadSocketsFds , CFRangeMake (0 , CFDataGetLength (__CFReadSocketsFds )), (UInt8 * )readfds );
13051367
@@ -1345,7 +1407,13 @@ static void *__CFSocketManager(void * arg)
13451407 }
13461408#endif
13471409
1410+ SInt32 error = 0 ;
13481411 nrfds = select (maxnrfds , readfds , writefds , exceptfds , pTimeout );
1412+ if (nrfds < 0 ) {
1413+ // Store error as early as possible, as the code below could
1414+ // reset it and make late check unreliable.
1415+ error = __CFSocketLastError ();
1416+ }
13491417
13501418#if defined(LOG_CFSOCKET ) && defined(DEBUG_POLLING_SELECT )
13511419 __CFSOCKETLOG ("socket manager woke from select, ret=%ld" , (long )nrfds );
@@ -1434,7 +1502,7 @@ static void *__CFSocketManager(void * arg)
14341502 }
14351503
14361504 if (0 > nrfds ) {
1437- manageSelectError ();
1505+ manageSelectError (error );
14381506 continue ;
14391507 }
14401508 if (FD_ISSET (__CFWakeupSocketPair [1 ], readfds )) {
0 commit comments