5151#include <process.h>
5252#endif
5353
54- #ifndef NBBY
55- #define NBBY 8
56- #endif
57-
5854#if TARGET_OS_WIN32
5955
6056// redefine this to the winsock error in this file
6561#undef EBADF
6662#define EBADF WSAENOTSOCK
6763
68- #define NFDBITS (sizeof(int32_t) * NBBY)
69-
70- typedef int32_t fd_mask ;
7164typedef int socklen_t ;
7265
7366#define gettimeofday _NS_gettimeofday
@@ -94,6 +87,12 @@ static void timeradd(struct timeval *a, struct timeval *b, struct timeval *res)
9487 }
9588}
9689
90+ #else
91+
92+ #ifndef NBBY
93+ #define NBBY 8
94+ #endif
95+
9796#endif // TARGET_OS_WIN32
9897
9998
@@ -214,10 +213,15 @@ CF_INLINE int __CFSocketLastError(void) {
214213
215214CF_INLINE CFIndex __CFSocketFdGetSize (CFDataRef fdSet ) {
216215#if TARGET_OS_WIN32
217- if (CFDataGetLength (fdSet ) == 0 ) {
216+ CFIndex dataLength = CFDataGetLength (fdSet );
217+ if (dataLength == 0 ) {
218218 return 0 ;
219219 }
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 ;
221225#else
222226 return NBBY * CFDataGetLength (fdSet );
223227#endif
@@ -229,13 +233,27 @@ CF_INLINE Boolean __CFSocketFdSet(CFSocketNativeHandle sock, CFMutableDataRef fd
229233 if (INVALID_SOCKET != sock && 0 <= sock ) {
230234 fd_set * fds ;
231235#if TARGET_OS_WIN32
236+ // Allocate initial fd_set if there is none
232237 if (CFDataGetLength (fdSet ) == 0 ) {
233238 CFDataIncreaseLength (fdSet , sizeof (fd_set ));
234239 fds = (fd_set * )CFDataGetMutableBytePtr (fdSet );
235240 FD_ZERO (fds );
236241 } else {
237242 fds = (fd_set * )CFDataGetMutableBytePtr (fdSet );
238243 }
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+ }
239257#else
240258 CFIndex numFds = NBBY * CFDataGetLength (fdSet );
241259 fd_mask * fds_bits ;
@@ -248,11 +266,11 @@ CF_INLINE Boolean __CFSocketFdSet(CFSocketNativeHandle sock, CFMutableDataRef fd
248266 fds_bits = (fd_mask * )CFDataGetMutableBytePtr (fdSet );
249267 }
250268 fds = (fd_set * )fds_bits ;
251- #endif
252269 if (!FD_ISSET (sock , fds )) {
253270 retval = true;
254271 FD_SET (sock , fds );
255272 }
273+ #endif
256274 }
257275 return retval ;
258276}
@@ -1223,20 +1241,20 @@ clearInvalidFileDescriptors(CFMutableDataRef d)
12231241 }
12241242
12251243 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
12291247 for (u_int idx = 0 ; idx < fds -> fd_count ; idx ++ ) {
12301248 SOCKET socket = fds -> fd_array [idx ];
12311249 if (! __CFNativeSocketIsValid (socket )) {
1232- FD_SET ( socket , & invalidFds ) ;
1250+ invalidFds [ count ++ ] = socket ;
12331251 }
12341252 }
12351253 // 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 );
12391256 }
1257+ free (invalidFds );
12401258#else
12411259 SInt32 count = __CFSocketFdGetSize (d );
12421260 fd_set * s = (fd_set * ) CFDataGetMutableBytePtr (d );
@@ -1309,15 +1327,19 @@ static void *__CFSocketManager(void * arg)
13091327#elif !TARGET_OS_CYGWIN && !TARGET_OS_BSD
13101328 pthread_setname_np ("com.apple.CFSocket.private" );
13111329#endif
1312- SInt32 nrfds , maxnrfds , fdentries = 1 ;
1313- SInt32 rfds , wfds ;
1330+ SInt32 nrfds , maxnrfds ;
13141331 fd_set * exceptfds = NULL ;
13151332#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 );
13181339 FD_ZERO (writefds );
13191340 FD_ZERO (readfds );
13201341#else
1342+ SInt32 rfds , wfds , fdentries = 1 ;
13211343 fd_set * writefds = (fd_set * )CFAllocatorAllocate (kCFAllocatorSystemDefault , fdentries * sizeof (fd_mask ), 0 );
13221344 fd_set * readfds = (fd_set * )CFAllocatorAllocate (kCFAllocatorSystemDefault , fdentries * sizeof (fd_mask ), 0 );
13231345#endif
@@ -1347,9 +1369,19 @@ static void *__CFSocketManager(void * arg)
13471369 free (writeBuffer );
13481370#endif
13491371
1372+ CFIndex rfdsDataLendth = CFDataGetLength (__CFReadSocketsFds );
1373+ CFIndex wfdsDataLength = CFDataGetLength (__CFWriteSocketsFds );
13501374#if TARGET_OS_WIN32
13511375 // This parameter is ignored by `select` from Winsock2 API
13521376 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+ }
13531385#else
13541386 rfds = __CFSocketFdGetSize (__CFReadSocketsFds );
13551387 wfds = __CFSocketFdGetSize (__CFWriteSocketsFds );
@@ -1362,8 +1394,8 @@ static void *__CFSocketManager(void * arg)
13621394 memset (writefds , 0 , fdentries * sizeof (fd_mask ));
13631395 memset (readfds , 0 , fdentries * sizeof (fd_mask ));
13641396#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 );
13671399
13681400 if (__CFReadSocketsTimeoutInvalid ) {
13691401 struct timeval * minTimeout = NULL ;
0 commit comments