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