@@ -215,13 +215,30 @@ CF_INLINE int __CFSocketLastError(void) {
215
215
}
216
216
217
217
CF_INLINE CFIndex __CFSocketFdGetSize (CFDataRef fdSet ) {
218
+ #if TARGET_OS_WIN32
219
+ if (CFDataGetLength (fdSet ) == 0 ) {
220
+ return 0 ;
221
+ }
222
+ return FD_SETSIZE ;
223
+ #else
218
224
return NBBY * CFDataGetLength (fdSet );
225
+ #endif
219
226
}
220
227
221
228
CF_INLINE Boolean __CFSocketFdSet (CFSocketNativeHandle sock , CFMutableDataRef fdSet ) {
222
229
/* returns true if a change occurred, false otherwise */
223
230
Boolean retval = false;
224
231
if (INVALID_SOCKET != sock && 0 <= sock ) {
232
+ fd_set * fds ;
233
+ #if TARGET_OS_WIN32
234
+ if (CFDataGetLength (fdSet ) == 0 ) {
235
+ CFDataIncreaseLength (fdSet , sizeof (fd_set ));
236
+ fds = (fd_set * )CFDataGetMutableBytePtr (fdSet );
237
+ FD_ZERO (fds );
238
+ } else {
239
+ fds = (fd_set * )CFDataGetMutableBytePtr (fdSet );
240
+ }
241
+ #else
225
242
CFIndex numFds = NBBY * CFDataGetLength (fdSet );
226
243
fd_mask * fds_bits ;
227
244
if (sock >= numFds ) {
@@ -232,9 +249,11 @@ CF_INLINE Boolean __CFSocketFdSet(CFSocketNativeHandle sock, CFMutableDataRef fd
232
249
} else {
233
250
fds_bits = (fd_mask * )CFDataGetMutableBytePtr (fdSet );
234
251
}
235
- if (!FD_ISSET (sock , (fd_set * )fds_bits )) {
252
+ fds = (fd_set * )fds_bits ;
253
+ #endif
254
+ if (!FD_ISSET (sock , fds )) {
236
255
retval = true;
237
- FD_SET (sock , ( fd_set * ) fds_bits );
256
+ FD_SET (sock , fds );
238
257
}
239
258
}
240
259
return retval ;
@@ -418,6 +437,15 @@ CF_INLINE Boolean __CFSocketFdClr(CFSocketNativeHandle sock, CFMutableDataRef fd
418
437
/* returns true if a change occurred, false otherwise */
419
438
Boolean retval = false;
420
439
if (INVALID_SOCKET != sock && 0 <= sock ) {
440
+ #if TARGET_OS_WIN32
441
+ if (CFDataGetLength (fdSet ) > 0 ) {
442
+ fd_set * fds = (fd_set * )CFDataGetMutableBytePtr (fdSet );
443
+ if (FD_ISSET (sock , fds )) {
444
+ retval = true;
445
+ FD_CLR (sock , fds );
446
+ }
447
+ }
448
+ #else
421
449
CFIndex numFds = NBBY * CFDataGetLength (fdSet );
422
450
fd_mask * fds_bits ;
423
451
if (sock < numFds ) {
@@ -427,6 +455,7 @@ CF_INLINE Boolean __CFSocketFdClr(CFSocketNativeHandle sock, CFMutableDataRef fd
427
455
FD_CLR (sock , (fd_set * )fds_bits );
428
456
}
429
457
}
458
+ #endif
430
459
}
431
460
return retval ;
432
461
}
@@ -1190,6 +1219,27 @@ static void
1190
1219
clearInvalidFileDescriptors (CFMutableDataRef d )
1191
1220
{
1192
1221
if (d ) {
1222
+ #if TARGET_OS_WIN32
1223
+ if (CFDataGetLength (d ) == 0 ) {
1224
+ return ;
1225
+ }
1226
+
1227
+ fd_set * fds = (fd_set * )CFDataGetMutableBytePtr (d );
1228
+ fd_set invalidFds ;
1229
+ FD_ZERO (& invalidFds );
1230
+ // Gather all invalid sockets into invalidFds set
1231
+ for (u_int idx = 0 ; idx < fds -> fd_count ; idx ++ ) {
1232
+ SOCKET socket = fds -> fd_array [idx ];
1233
+ if (! __CFNativeSocketIsValid (socket )) {
1234
+ FD_SET (socket , & invalidFds );
1235
+ }
1236
+ }
1237
+ // Remove invalid sockets from source set
1238
+ for (u_int idx = 0 ; idx < invalidFds .fd_count ; idx ++ ) {
1239
+ SOCKET socket = invalidFds .fd_array [idx ];
1240
+ FD_CLR (socket , fds );
1241
+ }
1242
+ #else
1193
1243
SInt32 count = __CFSocketFdGetSize (d );
1194
1244
fd_set * s = (fd_set * ) CFDataGetMutableBytePtr (d );
1195
1245
for (SInt32 idx = 0 ; idx < count ; idx ++ ) {
@@ -1198,14 +1248,13 @@ clearInvalidFileDescriptors(CFMutableDataRef d)
1198
1248
FD_CLR (idx , s );
1199
1249
}
1200
1250
}
1251
+ #endif
1201
1252
}
1202
1253
}
1203
1254
1204
1255
static void
1205
- manageSelectError ()
1256
+ manageSelectError (SInt32 selectError )
1206
1257
{
1207
- SInt32 selectError = __CFSocketLastError ();
1208
-
1209
1258
__CFSOCKETLOG ("socket manager received error %ld from select" , (long )selectError );
1210
1259
1211
1260
if (EBADF == selectError ) {
@@ -1265,8 +1314,15 @@ static void *__CFSocketManager(void * arg)
1265
1314
SInt32 nrfds , maxnrfds , fdentries = 1 ;
1266
1315
SInt32 rfds , wfds ;
1267
1316
fd_set * exceptfds = NULL ;
1317
+ #if TARGET_OS_WIN32
1318
+ fd_set * writefds = (fd_set * )CFAllocatorAllocate (kCFAllocatorSystemDefault , sizeof (fd_set ), 0 );
1319
+ fd_set * readfds = (fd_set * )CFAllocatorAllocate (kCFAllocatorSystemDefault , sizeof (fd_set ), 0 );
1320
+ FD_ZERO (writefds );
1321
+ FD_ZERO (readfds );
1322
+ #else
1268
1323
fd_set * writefds = (fd_set * )CFAllocatorAllocate (kCFAllocatorSystemDefault , fdentries * sizeof (fd_mask ), 0 );
1269
1324
fd_set * readfds = (fd_set * )CFAllocatorAllocate (kCFAllocatorSystemDefault , fdentries * sizeof (fd_mask ), 0 );
1325
+ #endif
1270
1326
fd_set * tempfds ;
1271
1327
SInt32 idx , cnt ;
1272
1328
uint8_t buffer [256 ];
@@ -1292,6 +1348,11 @@ static void *__CFSocketManager(void * arg)
1292
1348
free (readBuffer );
1293
1349
free (writeBuffer );
1294
1350
#endif
1351
+
1352
+ #if TARGET_OS_WIN32
1353
+ // This parameter is ignored by `select` from Winsock2 API
1354
+ maxnrfds = INT_MAX ;
1355
+ #else
1295
1356
rfds = __CFSocketFdGetSize (__CFReadSocketsFds );
1296
1357
wfds = __CFSocketFdGetSize (__CFWriteSocketsFds );
1297
1358
maxnrfds = __CFMax (rfds , wfds );
@@ -1302,6 +1363,7 @@ static void *__CFSocketManager(void * arg)
1302
1363
}
1303
1364
memset (writefds , 0 , fdentries * sizeof (fd_mask ));
1304
1365
memset (readfds , 0 , fdentries * sizeof (fd_mask ));
1366
+ #endif
1305
1367
CFDataGetBytes (__CFWriteSocketsFds , CFRangeMake (0 , CFDataGetLength (__CFWriteSocketsFds )), (UInt8 * )writefds );
1306
1368
CFDataGetBytes (__CFReadSocketsFds , CFRangeMake (0 , CFDataGetLength (__CFReadSocketsFds )), (UInt8 * )readfds );
1307
1369
@@ -1347,7 +1409,13 @@ static void *__CFSocketManager(void * arg)
1347
1409
}
1348
1410
#endif
1349
1411
1412
+ SInt32 error = 0 ;
1350
1413
nrfds = select (maxnrfds , readfds , writefds , exceptfds , pTimeout );
1414
+ if (nrfds < 0 ) {
1415
+ // Store error as early as possible, as the code below could
1416
+ // reset it and make late check unreliable.
1417
+ error = __CFSocketLastError ();
1418
+ }
1351
1419
1352
1420
#if defined(LOG_CFSOCKET ) && defined(DEBUG_POLLING_SELECT )
1353
1421
__CFSOCKETLOG ("socket manager woke from select, ret=%ld" , (long )nrfds );
@@ -1436,7 +1504,7 @@ static void *__CFSocketManager(void * arg)
1436
1504
}
1437
1505
1438
1506
if (0 > nrfds ) {
1439
- manageSelectError ();
1507
+ manageSelectError (error );
1440
1508
continue ;
1441
1509
}
1442
1510
if (FD_ISSET (__CFWakeupSocketPair [1 ], readfds )) {
0 commit comments