5353#include <process.h>
5454#endif
5555
56- #ifndef NBBY
57- #define NBBY 8
58- #endif
59-
6056#if TARGET_OS_WIN32
6157
6258// redefine this to the winsock error in this file
6763#undef EBADF
6864#define EBADF WSAENOTSOCK
6965
70- #define NFDBITS (sizeof(int32_t) * NBBY)
71-
72- typedef int32_t fd_mask ;
7366typedef int socklen_t ;
7467
7568#define gettimeofday _NS_gettimeofday
@@ -96,6 +89,12 @@ static void timeradd(struct timeval *a, struct timeval *b, struct timeval *res)
9689 }
9790}
9891
92+ #else
93+
94+ #ifndef NBBY
95+ #define NBBY 8
96+ #endif
97+
9998#endif // TARGET_OS_WIN32
10099
101100
@@ -216,10 +215,15 @@ CF_INLINE int __CFSocketLastError(void) {
216215
217216CF_INLINE CFIndex __CFSocketFdGetSize (CFDataRef fdSet ) {
218217#if TARGET_OS_WIN32
219- if (CFDataGetLength (fdSet ) == 0 ) {
218+ CFIndex dataLength = CFDataGetLength (fdSet );
219+ if (dataLength == 0 ) {
220220 return 0 ;
221221 }
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 ;
223227#else
224228 return NBBY * CFDataGetLength (fdSet );
225229#endif
@@ -231,13 +235,27 @@ CF_INLINE Boolean __CFSocketFdSet(CFSocketNativeHandle sock, CFMutableDataRef fd
231235 if (INVALID_SOCKET != sock && 0 <= sock ) {
232236 fd_set * fds ;
233237#if TARGET_OS_WIN32
238+ // Allocate initial fd_set if there is none
234239 if (CFDataGetLength (fdSet ) == 0 ) {
235240 CFDataIncreaseLength (fdSet , sizeof (fd_set ));
236241 fds = (fd_set * )CFDataGetMutableBytePtr (fdSet );
237242 FD_ZERO (fds );
238243 } else {
239244 fds = (fd_set * )CFDataGetMutableBytePtr (fdSet );
240245 }
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+ }
241259#else
242260 CFIndex numFds = NBBY * CFDataGetLength (fdSet );
243261 fd_mask * fds_bits ;
@@ -250,11 +268,11 @@ CF_INLINE Boolean __CFSocketFdSet(CFSocketNativeHandle sock, CFMutableDataRef fd
250268 fds_bits = (fd_mask * )CFDataGetMutableBytePtr (fdSet );
251269 }
252270 fds = (fd_set * )fds_bits ;
253- #endif
254271 if (!FD_ISSET (sock , fds )) {
255272 retval = true;
256273 FD_SET (sock , fds );
257274 }
275+ #endif
258276 }
259277 return retval ;
260278}
@@ -1225,20 +1243,20 @@ clearInvalidFileDescriptors(CFMutableDataRef d)
12251243 }
12261244
12271245 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
12311249 for (u_int idx = 0 ; idx < fds -> fd_count ; idx ++ ) {
12321250 SOCKET socket = fds -> fd_array [idx ];
12331251 if (! __CFNativeSocketIsValid (socket )) {
1234- FD_SET ( socket , & invalidFds ) ;
1252+ invalidFds [ count ++ ] = socket ;
12351253 }
12361254 }
12371255 // 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 );
12411258 }
1259+ free (invalidFds );
12421260#else
12431261 SInt32 count = __CFSocketFdGetSize (d );
12441262 fd_set * s = (fd_set * ) CFDataGetMutableBytePtr (d );
@@ -1311,15 +1329,19 @@ static void *__CFSocketManager(void * arg)
13111329#elif !TARGET_OS_CYGWIN && !TARGET_OS_BSD
13121330 pthread_setname_np ("com.apple.CFSocket.private" );
13131331#endif
1314- SInt32 nrfds , maxnrfds , fdentries = 1 ;
1315- SInt32 rfds , wfds ;
1332+ SInt32 nrfds , maxnrfds ;
13161333 fd_set * exceptfds = NULL ;
13171334#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 );
13201341 FD_ZERO (writefds );
13211342 FD_ZERO (readfds );
13221343#else
1344+ SInt32 rfds , wfds , fdentries = 1 ;
13231345 fd_set * writefds = (fd_set * )CFAllocatorAllocate (kCFAllocatorSystemDefault , fdentries * sizeof (fd_mask ), 0 );
13241346 fd_set * readfds = (fd_set * )CFAllocatorAllocate (kCFAllocatorSystemDefault , fdentries * sizeof (fd_mask ), 0 );
13251347#endif
@@ -1349,9 +1371,19 @@ static void *__CFSocketManager(void * arg)
13491371 free (writeBuffer );
13501372#endif
13511373
1374+ CFIndex rfdsDataLendth = CFDataGetLength (__CFReadSocketsFds );
1375+ CFIndex wfdsDataLength = CFDataGetLength (__CFWriteSocketsFds );
13521376#if TARGET_OS_WIN32
13531377 // This parameter is ignored by `select` from Winsock2 API
13541378 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+ }
13551387#else
13561388 rfds = __CFSocketFdGetSize (__CFReadSocketsFds );
13571389 wfds = __CFSocketFdGetSize (__CFWriteSocketsFds );
@@ -1364,8 +1396,8 @@ static void *__CFSocketManager(void * arg)
13641396 memset (writefds , 0 , fdentries * sizeof (fd_mask ));
13651397 memset (readfds , 0 , fdentries * sizeof (fd_mask ));
13661398#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 );
13691401
13701402 if (__CFReadSocketsTimeoutInvalid ) {
13711403 struct timeval * minTimeout = NULL ;
0 commit comments