@@ -1086,12 +1086,10 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
1086
1086
unsigned int curlfds ;
1087
1087
long timeout_internal ;
1088
1088
int retcode = 0 ;
1089
- #ifndef USE_WINSOCK
1090
1089
struct pollfd a_few_on_stack [NUM_POLLS_ON_STACK ];
1091
1090
struct pollfd * ufds = & a_few_on_stack [0 ];
1092
1091
bool ufds_malloc = FALSE;
1093
- #else
1094
- struct pollfd pre_poll ;
1092
+ #ifdef USE_WINSOCK
1095
1093
WSANETWORKEVENTS wsa_events ;
1096
1094
DEBUGASSERT (multi -> wsa_event != WSA_INVALID_EVENT );
1097
1095
#endif
@@ -1149,7 +1147,6 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
1149
1147
}
1150
1148
#endif
1151
1149
1152
- #ifndef USE_WINSOCK
1153
1150
if (nfds > NUM_POLLS_ON_STACK ) {
1154
1151
/* 'nfds' is a 32 bit value and 'struct pollfd' is typically 8 bytes
1155
1152
big, so at 2^29 sockets this value might wrap. When a process gets
@@ -1160,9 +1157,7 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
1160
1157
return CURLM_OUT_OF_MEMORY ;
1161
1158
ufds_malloc = TRUE;
1162
1159
}
1163
-
1164
1160
nfds = 0 ;
1165
- #endif
1166
1161
1167
1162
/* only do the second loop if we found descriptors in the first stage run
1168
1163
above */
@@ -1180,34 +1175,31 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
1180
1175
#endif
1181
1176
if (bitmap & GETSOCK_READSOCK (i )) {
1182
1177
#ifdef USE_WINSOCK
1183
- if (timeout_ms && SOCKET_READABLE (sockbunch [i ], 0 ) > 0 )
1184
- timeout_ms = 0 ;
1185
1178
mask |= FD_READ |FD_ACCEPT |FD_CLOSE ;
1186
- #else
1179
+ #endif
1187
1180
ufds [nfds ].fd = sockbunch [i ];
1188
1181
ufds [nfds ].events = POLLIN ;
1189
1182
++ nfds ;
1190
- #endif
1191
1183
s = sockbunch [i ];
1192
1184
}
1193
1185
if (bitmap & GETSOCK_WRITESOCK (i )) {
1194
1186
#ifdef USE_WINSOCK
1195
- if (timeout_ms && SOCKET_WRITABLE (sockbunch [i ], 0 ) > 0 )
1196
- timeout_ms = 0 ;
1197
1187
mask |= FD_WRITE |FD_CONNECT |FD_CLOSE ;
1198
- #else
1188
+ #endif
1199
1189
ufds [nfds ].fd = sockbunch [i ];
1200
1190
ufds [nfds ].events = POLLOUT ;
1201
1191
++ nfds ;
1202
- #endif
1203
1192
s = sockbunch [i ];
1204
1193
}
1205
1194
if (s == CURL_SOCKET_BAD ) {
1206
1195
break ;
1207
1196
}
1208
1197
#ifdef USE_WINSOCK
1209
- if (WSAEventSelect (s , multi -> wsa_event , mask ) != 0 )
1198
+ if (WSAEventSelect (s , multi -> wsa_event , mask ) != 0 ) {
1199
+ if (ufds_malloc )
1200
+ free (ufds );
1210
1201
return CURLM_INTERNAL_ERROR ;
1202
+ }
1211
1203
#endif
1212
1204
}
1213
1205
@@ -1219,35 +1211,18 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
1219
1211
for (i = 0 ; i < extra_nfds ; i ++ ) {
1220
1212
#ifdef USE_WINSOCK
1221
1213
long mask = 0 ;
1222
- extra_fds [i ].revents = 0 ;
1223
- pre_poll .fd = extra_fds [i ].fd ;
1224
- pre_poll .events = 0 ;
1225
- pre_poll .revents = 0 ;
1226
- if (extra_fds [i ].events & CURL_WAIT_POLLIN ) {
1214
+ if (extra_fds [i ].events & CURL_WAIT_POLLIN )
1227
1215
mask |= FD_READ |FD_ACCEPT |FD_CLOSE ;
1228
- pre_poll .events |= POLLIN ;
1229
- }
1230
- if (extra_fds [i ].events & CURL_WAIT_POLLPRI ) {
1216
+ if (extra_fds [i ].events & CURL_WAIT_POLLPRI )
1231
1217
mask |= FD_OOB ;
1232
- pre_poll .events |= POLLPRI ;
1233
- }
1234
- if (extra_fds [i ].events & CURL_WAIT_POLLOUT ) {
1218
+ if (extra_fds [i ].events & CURL_WAIT_POLLOUT )
1235
1219
mask |= FD_WRITE |FD_CONNECT |FD_CLOSE ;
1236
- pre_poll .events |= POLLOUT ;
1237
- }
1238
- if (Curl_poll (& pre_poll , 1 , 0 ) > 0 ) {
1239
- if (pre_poll .revents & POLLIN )
1240
- extra_fds [i ].revents |= CURL_WAIT_POLLIN ;
1241
- if (pre_poll .revents & POLLPRI )
1242
- extra_fds [i ].revents |= CURL_WAIT_POLLPRI ;
1243
- if (pre_poll .revents & POLLOUT )
1244
- extra_fds [i ].revents |= CURL_WAIT_POLLOUT ;
1245
- if (extra_fds [i ].revents )
1246
- timeout_ms = 0 ;
1247
- }
1248
- if (WSAEventSelect (extra_fds [i ].fd , multi -> wsa_event , mask ) != 0 )
1220
+ if (WSAEventSelect (extra_fds [i ].fd , multi -> wsa_event , mask ) != 0 ) {
1221
+ if (ufds_malloc )
1222
+ free (ufds );
1249
1223
return CURLM_INTERNAL_ERROR ;
1250
- #else
1224
+ }
1225
+ #endif
1251
1226
ufds [nfds ].fd = extra_fds [i ].fd ;
1252
1227
ufds [nfds ].events = 0 ;
1253
1228
if (extra_fds [i ].events & CURL_WAIT_POLLIN )
@@ -1257,7 +1232,6 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
1257
1232
if (extra_fds [i ].events & CURL_WAIT_POLLOUT )
1258
1233
ufds [nfds ].events |= POLLOUT ;
1259
1234
++ nfds ;
1260
- #endif
1261
1235
}
1262
1236
1263
1237
#ifdef ENABLE_WAKEUP
@@ -1270,53 +1244,59 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
1270
1244
#endif
1271
1245
#endif
1272
1246
1247
+ #if defined(ENABLE_WAKEUP ) && defined(USE_WINSOCK )
1248
+ if (nfds || use_wakeup ) {
1249
+ #else
1273
1250
if (nfds ) {
1274
- /* wait... */
1251
+ #endif
1252
+ int pollrc ;
1275
1253
#ifdef USE_WINSOCK
1276
- WSAWaitForMultipleEvents (1 , & multi -> wsa_event , FALSE, timeout_ms , FALSE);
1254
+ if (nfds )
1255
+ pollrc = Curl_poll (ufds , nfds , 0 ); /* just pre-check with WinSock */
1256
+ else
1257
+ pollrc = 0 ;
1258
+ if (pollrc <= 0 ) /* now wait... if not ready during the pre-check above */
1259
+ WSAWaitForMultipleEvents (1 , & multi -> wsa_event , FALSE, timeout_ms , FALSE);
1277
1260
#else
1278
- int pollrc = Curl_poll (ufds , nfds , timeout_ms );
1261
+ pollrc = Curl_poll (ufds , nfds , timeout_ms ); /* wait... */
1279
1262
#endif
1280
1263
1281
- #ifdef USE_WINSOCK
1282
- /* With Winsock, we have to run this unconditionally to call
1283
- WSAEventSelect(fd, event, 0) on all the sockets */
1284
- {
1285
- retcode = 0 ;
1286
- #else
1287
1264
if (pollrc > 0 ) {
1288
1265
retcode = pollrc ;
1266
+ #ifdef USE_WINSOCK
1267
+ }
1268
+ /* With WinSock, we have to run the following section unconditionally
1269
+ to call WSAEventSelect(fd, event, 0) on all the sockets */
1270
+ {
1289
1271
#endif
1290
1272
/* copy revents results from the poll to the curl_multi_wait poll
1291
1273
struct, the bit values of the actual underlying poll() implementation
1292
1274
may not be the same as the ones in the public libcurl API! */
1293
1275
for (i = 0 ; i < extra_nfds ; i ++ ) {
1276
+ unsigned r = ufds [curlfds + i ].revents ;
1294
1277
unsigned short mask = 0 ;
1295
1278
#ifdef USE_WINSOCK
1296
1279
wsa_events .lNetworkEvents = 0 ;
1297
- mask = extra_fds [i ].revents ;
1298
- if (WSAEnumNetworkEvents (extra_fds [i ].fd , multi -> wsa_event ,
1299
- & wsa_events ) == 0 ) {
1280
+ if (WSAEnumNetworkEvents (extra_fds [i ].fd , NULL , & wsa_events ) == 0 ) {
1300
1281
if (wsa_events .lNetworkEvents & (FD_READ |FD_ACCEPT |FD_CLOSE ))
1301
1282
mask |= CURL_WAIT_POLLIN ;
1302
1283
if (wsa_events .lNetworkEvents & (FD_WRITE |FD_CONNECT |FD_CLOSE ))
1303
1284
mask |= CURL_WAIT_POLLOUT ;
1304
1285
if (wsa_events .lNetworkEvents & FD_OOB )
1305
1286
mask |= CURL_WAIT_POLLPRI ;
1306
- if (ret && wsa_events .lNetworkEvents != 0 )
1287
+ if (ret && pollrc <= 0 && wsa_events .lNetworkEvents != 0 )
1307
1288
retcode ++ ;
1308
1289
}
1309
1290
WSAEventSelect (extra_fds [i ].fd , multi -> wsa_event , 0 );
1310
- #else
1311
- unsigned r = ufds [ curlfds + i ]. revents ;
1312
-
1291
+ if ( pollrc <= 0 )
1292
+ continue ;
1293
+ #endif
1313
1294
if (r & POLLIN )
1314
1295
mask |= CURL_WAIT_POLLIN ;
1315
1296
if (r & POLLOUT )
1316
1297
mask |= CURL_WAIT_POLLOUT ;
1317
1298
if (r & POLLPRI )
1318
1299
mask |= CURL_WAIT_POLLPRI ;
1319
- #endif
1320
1300
extra_fds [i ].revents = mask ;
1321
1301
}
1322
1302
@@ -1331,17 +1311,8 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
1331
1311
for (i = 0 ; i < MAX_SOCKSPEREASYHANDLE ; i ++ ) {
1332
1312
if (bitmap & (GETSOCK_READSOCK (i ) | GETSOCK_WRITESOCK (i ))) {
1333
1313
wsa_events .lNetworkEvents = 0 ;
1334
- if (WSAEnumNetworkEvents (sockbunch [i ], multi -> wsa_event ,
1335
- & wsa_events ) == 0 ) {
1336
- if (ret && wsa_events .lNetworkEvents != 0 )
1337
- retcode ++ ;
1338
- }
1339
- if (ret && !timeout_ms && wsa_events .lNetworkEvents == 0 ) {
1340
- if ((bitmap & GETSOCK_READSOCK (i )) &&
1341
- SOCKET_READABLE (sockbunch [i ], 0 ) > 0 )
1342
- retcode ++ ;
1343
- else if ((bitmap & GETSOCK_WRITESOCK (i )) &&
1344
- SOCKET_WRITABLE (sockbunch [i ], 0 ) > 0 )
1314
+ if (WSAEnumNetworkEvents (sockbunch [i ], NULL , & wsa_events ) == 0 ) {
1315
+ if (ret && pollrc <= 0 && wsa_events .lNetworkEvents != 0 )
1345
1316
retcode ++ ;
1346
1317
}
1347
1318
WSAEventSelect (sockbunch [i ], multi -> wsa_event , 0 );
@@ -1382,16 +1353,15 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
1382
1353
}
1383
1354
}
1384
1355
1385
- #ifndef USE_WINSOCK
1386
1356
if (ufds_malloc )
1387
1357
free (ufds );
1388
- #endif
1389
1358
if (ret )
1390
1359
* ret = retcode ;
1391
- if (!extrawait || nfds )
1392
- /* if any socket was checked */
1393
- ;
1394
- else {
1360
+ #if defined(ENABLE_WAKEUP ) && defined(USE_WINSOCK )
1361
+ if (extrawait && !nfds && !use_wakeup ) {
1362
+ #else
1363
+ if (extrawait && !nfds ) {
1364
+ #endif
1395
1365
long sleep_ms = 0 ;
1396
1366
1397
1367
/* Avoid busy-looping when there's nothing particular to wait for */
0 commit comments