51
51
#include <process.h>
52
52
#endif
53
53
54
- #ifndef NBBY
55
- #define NBBY 8
56
- #endif
57
-
58
54
#if TARGET_OS_WIN32
59
55
60
56
// redefine this to the winsock error in this file
65
61
#undef EBADF
66
62
#define EBADF WSAENOTSOCK
67
63
68
- #define NFDBITS (sizeof(int32_t) * NBBY)
69
-
70
- typedef int32_t fd_mask ;
71
64
typedef int socklen_t ;
72
65
73
66
#define gettimeofday _NS_gettimeofday
@@ -94,6 +87,12 @@ static void timeradd(struct timeval *a, struct timeval *b, struct timeval *res)
94
87
}
95
88
}
96
89
90
+ #else
91
+
92
+ #ifndef NBBY
93
+ #define NBBY 8
94
+ #endif
95
+
97
96
#endif // TARGET_OS_WIN32
98
97
99
98
@@ -214,10 +213,15 @@ CF_INLINE int __CFSocketLastError(void) {
214
213
215
214
CF_INLINE CFIndex __CFSocketFdGetSize (CFDataRef fdSet ) {
216
215
#if TARGET_OS_WIN32
217
- if (CFDataGetLength (fdSet ) == 0 ) {
216
+ CFIndex dataLength = CFDataGetLength (fdSet );
217
+ if (dataLength == 0 ) {
218
218
return 0 ;
219
219
}
220
- return FD_SETSIZE ;
220
+ // The minimal possible capacity we could possibly have
221
+ // equals to FD_SETSIZE (as part of fd_set structure).
222
+ // All additional data length is the space for SOCKETs
223
+ // over fd_set static buffer limit.
224
+ return (dataLength - sizeof (fd_set )) / sizeof (SOCKET ) + FD_SETSIZE ;
221
225
#else
222
226
return NBBY * CFDataGetLength (fdSet );
223
227
#endif
@@ -229,13 +233,27 @@ CF_INLINE Boolean __CFSocketFdSet(CFSocketNativeHandle sock, CFMutableDataRef fd
229
233
if (INVALID_SOCKET != sock && 0 <= sock ) {
230
234
fd_set * fds ;
231
235
#if TARGET_OS_WIN32
236
+ // Allocate initial fd_set if there is none
232
237
if (CFDataGetLength (fdSet ) == 0 ) {
233
238
CFDataIncreaseLength (fdSet , sizeof (fd_set ));
234
239
fds = (fd_set * )CFDataGetMutableBytePtr (fdSet );
235
240
FD_ZERO (fds );
236
241
} else {
237
242
fds = (fd_set * )CFDataGetMutableBytePtr (fdSet );
238
243
}
244
+
245
+ // FD_SET macro replacement with growable storage
246
+ if (!FD_ISSET (sock , fds )) {
247
+ retval = true;
248
+ u_int count = fds -> fd_count ;
249
+ if (count >= __CFSocketFdGetSize (fdSet )) {
250
+ CFDataIncreaseLength (fdSet , FD_SETSIZE * sizeof (SOCKET ));
251
+ fds = (fd_set * )CFDataGetMutableBytePtr (fdSet );
252
+ }
253
+
254
+ fds -> fd_array [count ] = sock ;
255
+ fds -> fd_count ++ ;
256
+ }
239
257
#else
240
258
CFIndex numFds = NBBY * CFDataGetLength (fdSet );
241
259
fd_mask * fds_bits ;
@@ -248,11 +266,11 @@ CF_INLINE Boolean __CFSocketFdSet(CFSocketNativeHandle sock, CFMutableDataRef fd
248
266
fds_bits = (fd_mask * )CFDataGetMutableBytePtr (fdSet );
249
267
}
250
268
fds = (fd_set * )fds_bits ;
251
- #endif
252
269
if (!FD_ISSET (sock , fds )) {
253
270
retval = true;
254
271
FD_SET (sock , fds );
255
272
}
273
+ #endif
256
274
}
257
275
return retval ;
258
276
}
@@ -1223,20 +1241,20 @@ clearInvalidFileDescriptors(CFMutableDataRef d)
1223
1241
}
1224
1242
1225
1243
fd_set * fds = (fd_set * )CFDataGetMutableBytePtr (d );
1226
- fd_set invalidFds ;
1227
- FD_ZERO ( & invalidFds );
1228
- // Gather all invalid sockets into invalidFds set
1244
+ u_int count = 0 ;
1245
+ SOCKET * invalidFds = malloc ( sizeof ( SOCKET ) * fds -> fd_count );
1246
+ // Gather all invalid sockets
1229
1247
for (u_int idx = 0 ; idx < fds -> fd_count ; idx ++ ) {
1230
1248
SOCKET socket = fds -> fd_array [idx ];
1231
1249
if (! __CFNativeSocketIsValid (socket )) {
1232
- FD_SET ( socket , & invalidFds ) ;
1250
+ invalidFds [ count ++ ] = socket ;
1233
1251
}
1234
1252
}
1235
1253
// 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 );
1254
+ for (u_int idx = 0 ; idx < count ; idx ++ ) {
1255
+ FD_CLR (invalidFds [idx ], fds );
1239
1256
}
1257
+ free (invalidFds );
1240
1258
#else
1241
1259
SInt32 count = __CFSocketFdGetSize (d );
1242
1260
fd_set * s = (fd_set * ) CFDataGetMutableBytePtr (d );
@@ -1309,15 +1327,19 @@ static void *__CFSocketManager(void * arg)
1309
1327
#elif !TARGET_OS_CYGWIN && !TARGET_OS_BSD
1310
1328
pthread_setname_np ("com.apple.CFSocket.private" );
1311
1329
#endif
1312
- SInt32 nrfds , maxnrfds , fdentries = 1 ;
1313
- SInt32 rfds , wfds ;
1330
+ SInt32 nrfds , maxnrfds ;
1314
1331
fd_set * exceptfds = NULL ;
1315
1332
#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 );
1333
+ CFMutableDataRef writeFdsData = CFDataCreateMutable (kCFAllocatorSystemDefault , 0 );
1334
+ CFMutableDataRef readFdsData = CFDataCreateMutable (kCFAllocatorSystemDefault , 0 );
1335
+ CFDataSetLength (writeFdsData , sizeof (fd_set ));
1336
+ CFDataSetLength (readFdsData , sizeof (fd_set ));
1337
+ fd_set * writefds = (fd_set * )CFDataGetMutableBytePtr (writeFdsData );
1338
+ fd_set * readfds = (fd_set * )CFDataGetMutableBytePtr (readFdsData );
1318
1339
FD_ZERO (writefds );
1319
1340
FD_ZERO (readfds );
1320
1341
#else
1342
+ SInt32 rfds , wfds , fdentries = 1 ;
1321
1343
fd_set * writefds = (fd_set * )CFAllocatorAllocate (kCFAllocatorSystemDefault , fdentries * sizeof (fd_mask ), 0 );
1322
1344
fd_set * readfds = (fd_set * )CFAllocatorAllocate (kCFAllocatorSystemDefault , fdentries * sizeof (fd_mask ), 0 );
1323
1345
#endif
@@ -1347,9 +1369,19 @@ static void *__CFSocketManager(void * arg)
1347
1369
free (writeBuffer );
1348
1370
#endif
1349
1371
1372
+ CFIndex rfdsDataLendth = CFDataGetLength (__CFReadSocketsFds );
1373
+ CFIndex wfdsDataLength = CFDataGetLength (__CFWriteSocketsFds );
1350
1374
#if TARGET_OS_WIN32
1351
1375
// This parameter is ignored by `select` from Winsock2 API
1352
1376
maxnrfds = INT_MAX ;
1377
+ // Note that writeFdsData and rfdsDataLendth lengths are equal
1378
+ CFIndex dataLengthDiff = __CFMax (rfdsDataLendth , wfdsDataLength ) - CFDataGetLength (writeFdsData );
1379
+ if (dataLengthDiff > 0 ) {
1380
+ CFDataIncreaseLength (writeFdsData , dataLengthDiff );
1381
+ CFDataIncreaseLength (readFdsData , dataLengthDiff );
1382
+ writefds = (fd_set * )CFDataGetMutableBytePtr (writeFdsData );
1383
+ readfds = (fd_set * )CFDataGetMutableBytePtr (readFdsData );
1384
+ }
1353
1385
#else
1354
1386
rfds = __CFSocketFdGetSize (__CFReadSocketsFds );
1355
1387
wfds = __CFSocketFdGetSize (__CFWriteSocketsFds );
@@ -1362,8 +1394,8 @@ static void *__CFSocketManager(void * arg)
1362
1394
memset (writefds , 0 , fdentries * sizeof (fd_mask ));
1363
1395
memset (readfds , 0 , fdentries * sizeof (fd_mask ));
1364
1396
#endif
1365
- CFDataGetBytes (__CFWriteSocketsFds , CFRangeMake (0 , CFDataGetLength ( __CFWriteSocketsFds ) ), (UInt8 * )writefds );
1366
- CFDataGetBytes (__CFReadSocketsFds , CFRangeMake (0 , CFDataGetLength ( __CFReadSocketsFds ) ), (UInt8 * )readfds );
1397
+ CFDataGetBytes (__CFWriteSocketsFds , CFRangeMake (0 , wfdsDataLength ), (UInt8 * )writefds );
1398
+ CFDataGetBytes (__CFReadSocketsFds , CFRangeMake (0 , rfdsDataLendth ), (UInt8 * )readfds );
1367
1399
1368
1400
if (__CFReadSocketsTimeoutInvalid ) {
1369
1401
struct timeval * minTimeout = NULL ;
0 commit comments