@@ -213,13 +213,30 @@ CF_INLINE int __CFSocketLastError(void) {
213
213
}
214
214
215
215
CF_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
216
222
return NBBY * CFDataGetLength (fdSet );
223
+ #endif
217
224
}
218
225
219
226
CF_INLINE Boolean __CFSocketFdSet (CFSocketNativeHandle sock , CFMutableDataRef fdSet ) {
220
227
/* returns true if a change occurred, false otherwise */
221
228
Boolean retval = false;
222
229
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
223
240
CFIndex numFds = NBBY * CFDataGetLength (fdSet );
224
241
fd_mask * fds_bits ;
225
242
if (sock >= numFds ) {
@@ -230,9 +247,11 @@ CF_INLINE Boolean __CFSocketFdSet(CFSocketNativeHandle sock, CFMutableDataRef fd
230
247
} else {
231
248
fds_bits = (fd_mask * )CFDataGetMutableBytePtr (fdSet );
232
249
}
233
- if (!FD_ISSET (sock , (fd_set * )fds_bits )) {
250
+ fds = (fd_set * )fds_bits ;
251
+ #endif
252
+ if (!FD_ISSET (sock , fds )) {
234
253
retval = true;
235
- FD_SET (sock , ( fd_set * ) fds_bits );
254
+ FD_SET (sock , fds );
236
255
}
237
256
}
238
257
return retval ;
@@ -416,6 +435,15 @@ CF_INLINE Boolean __CFSocketFdClr(CFSocketNativeHandle sock, CFMutableDataRef fd
416
435
/* returns true if a change occurred, false otherwise */
417
436
Boolean retval = false;
418
437
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
419
447
CFIndex numFds = NBBY * CFDataGetLength (fdSet );
420
448
fd_mask * fds_bits ;
421
449
if (sock < numFds ) {
@@ -425,6 +453,7 @@ CF_INLINE Boolean __CFSocketFdClr(CFSocketNativeHandle sock, CFMutableDataRef fd
425
453
FD_CLR (sock , (fd_set * )fds_bits );
426
454
}
427
455
}
456
+ #endif
428
457
}
429
458
return retval ;
430
459
}
@@ -1188,6 +1217,27 @@ static void
1188
1217
clearInvalidFileDescriptors (CFMutableDataRef d )
1189
1218
{
1190
1219
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
1191
1241
SInt32 count = __CFSocketFdGetSize (d );
1192
1242
fd_set * s = (fd_set * ) CFDataGetMutableBytePtr (d );
1193
1243
for (SInt32 idx = 0 ; idx < count ; idx ++ ) {
@@ -1196,14 +1246,13 @@ clearInvalidFileDescriptors(CFMutableDataRef d)
1196
1246
FD_CLR (idx , s );
1197
1247
}
1198
1248
}
1249
+ #endif
1199
1250
}
1200
1251
}
1201
1252
1202
1253
static void
1203
- manageSelectError ()
1254
+ manageSelectError (SInt32 selectError )
1204
1255
{
1205
- SInt32 selectError = __CFSocketLastError ();
1206
-
1207
1256
__CFSOCKETLOG ("socket manager received error %ld from select" , (long )selectError );
1208
1257
1209
1258
if (EBADF == selectError ) {
@@ -1263,8 +1312,15 @@ static void *__CFSocketManager(void * arg)
1263
1312
SInt32 nrfds , maxnrfds , fdentries = 1 ;
1264
1313
SInt32 rfds , wfds ;
1265
1314
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
1266
1321
fd_set * writefds = (fd_set * )CFAllocatorAllocate (kCFAllocatorSystemDefault , fdentries * sizeof (fd_mask ), 0 );
1267
1322
fd_set * readfds = (fd_set * )CFAllocatorAllocate (kCFAllocatorSystemDefault , fdentries * sizeof (fd_mask ), 0 );
1323
+ #endif
1268
1324
fd_set * tempfds ;
1269
1325
SInt32 idx , cnt ;
1270
1326
uint8_t buffer [256 ];
@@ -1290,6 +1346,11 @@ static void *__CFSocketManager(void * arg)
1290
1346
free (readBuffer );
1291
1347
free (writeBuffer );
1292
1348
#endif
1349
+
1350
+ #if TARGET_OS_WIN32
1351
+ // This parameter is ignored by `select` from Winsock2 API
1352
+ maxnrfds = INT_MAX ;
1353
+ #else
1293
1354
rfds = __CFSocketFdGetSize (__CFReadSocketsFds );
1294
1355
wfds = __CFSocketFdGetSize (__CFWriteSocketsFds );
1295
1356
maxnrfds = __CFMax (rfds , wfds );
@@ -1300,6 +1361,7 @@ static void *__CFSocketManager(void * arg)
1300
1361
}
1301
1362
memset (writefds , 0 , fdentries * sizeof (fd_mask ));
1302
1363
memset (readfds , 0 , fdentries * sizeof (fd_mask ));
1364
+ #endif
1303
1365
CFDataGetBytes (__CFWriteSocketsFds , CFRangeMake (0 , CFDataGetLength (__CFWriteSocketsFds )), (UInt8 * )writefds );
1304
1366
CFDataGetBytes (__CFReadSocketsFds , CFRangeMake (0 , CFDataGetLength (__CFReadSocketsFds )), (UInt8 * )readfds );
1305
1367
@@ -1345,7 +1407,13 @@ static void *__CFSocketManager(void * arg)
1345
1407
}
1346
1408
#endif
1347
1409
1410
+ SInt32 error = 0 ;
1348
1411
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
+ }
1349
1417
1350
1418
#if defined(LOG_CFSOCKET ) && defined(DEBUG_POLLING_SELECT )
1351
1419
__CFSOCKETLOG ("socket manager woke from select, ret=%ld" , (long )nrfds );
@@ -1434,7 +1502,7 @@ static void *__CFSocketManager(void * arg)
1434
1502
}
1435
1503
1436
1504
if (0 > nrfds ) {
1437
- manageSelectError ();
1505
+ manageSelectError (error );
1438
1506
continue ;
1439
1507
}
1440
1508
if (FD_ISSET (__CFWakeupSocketPair [1 ], readfds )) {
0 commit comments