diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/util/network.c | 69 |
1 files changed, 64 insertions, 5 deletions
diff --git a/src/util/network.c b/src/util/network.c index bef285bee..6a7453510 100644 --- a/src/util/network.c +++ b/src/util/network.c | |||
@@ -1152,7 +1152,7 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, | |||
1152 | 1152 | ||
1153 | #if DEBUG_W32_CYCLES | 1153 | #if DEBUG_W32_CYCLES |
1154 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1154 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1155 | "Starting a cycle, delay is %dms\n", cycle_delay); | 1155 | "Starting a cycle, delay is %dms. nfds is %d.\n", cycle_delay, nfds); |
1156 | #endif | 1156 | #endif |
1157 | 1157 | ||
1158 | limit = GetTickCount () + ms_total; | 1158 | limit = GetTickCount () + ms_total; |
@@ -1171,6 +1171,30 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, | |||
1171 | FD_COPY (&sock_except, &aexcept); | 1171 | FD_COPY (&sock_except, &aexcept); |
1172 | tvslice.tv_sec = 0; | 1172 | tvslice.tv_sec = 0; |
1173 | tvslice.tv_usec = cycle_delay; | 1173 | tvslice.tv_usec = cycle_delay; |
1174 | #if DEBUG_W32_CYCLES | ||
1175 | { | ||
1176 | for (i = 0; i < nfds; i++) | ||
1177 | { | ||
1178 | if (SAFE_FD_ISSET (i, &sock_read)) | ||
1179 | { | ||
1180 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1181 | "Going to select socket %d for reading\n", i); | ||
1182 | } | ||
1183 | if (SAFE_FD_ISSET (i, &sock_write)) | ||
1184 | { | ||
1185 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1186 | "Going to select socket %d for writing\n", i); | ||
1187 | } | ||
1188 | if (SAFE_FD_ISSET (i, &sock_except)) | ||
1189 | { | ||
1190 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1191 | "Going to select socket %d for exceptions\n", i); | ||
1192 | } | ||
1193 | } | ||
1194 | } | ||
1195 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1196 | "Waiting for %d microseconds, %d left\n", cycle_delay, (limit - GetTickCount ())*1000); | ||
1197 | #endif | ||
1174 | if ((retcode = | 1198 | if ((retcode = |
1175 | select (nfds + 1, &aread, &awrite, &aexcept, | 1199 | select (nfds + 1, &aread, &awrite, &aexcept, |
1176 | &tvslice)) == SOCKET_ERROR) | 1200 | &tvslice)) == SOCKET_ERROR) |
@@ -1186,13 +1210,20 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, | |||
1186 | #endif | 1210 | #endif |
1187 | goto select_loop_end; | 1211 | goto select_loop_end; |
1188 | } | 1212 | } |
1213 | #if DEBUG_W32_CYCLES | ||
1214 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1215 | "Select () returned %d, GLE is %d\n", retcode, GetLastError ()); | ||
1216 | #endif | ||
1189 | } | 1217 | } |
1190 | 1218 | ||
1191 | /* Poll read pipes */ | 1219 | /* Poll read pipes */ |
1192 | if (rfds) | 1220 | if (rfds) |
1193 | |||
1194 | { | 1221 | { |
1195 | struct GNUNET_CONTAINER_SList_Iterator *i; | 1222 | struct GNUNET_CONTAINER_SList_Iterator *i; |
1223 | #if DEBUG_W32_CYCLES | ||
1224 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1225 | "Polling rfds for readable pipes\n"); | ||
1226 | #endif | ||
1196 | for (i = GNUNET_CONTAINER_slist_begin (rfds->handles); | 1227 | for (i = GNUNET_CONTAINER_slist_begin (rfds->handles); |
1197 | GNUNET_CONTAINER_slist_end (i) != GNUNET_YES; | 1228 | GNUNET_CONTAINER_slist_end (i) != GNUNET_YES; |
1198 | GNUNET_CONTAINER_slist_next (i)) | 1229 | GNUNET_CONTAINER_slist_next (i)) |
@@ -1203,6 +1234,10 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, | |||
1203 | fh = (struct GNUNET_DISK_FileHandle *) GNUNET_CONTAINER_slist_get (i, NULL); | 1234 | fh = (struct GNUNET_DISK_FileHandle *) GNUNET_CONTAINER_slist_get (i, NULL); |
1204 | if (fh->type == GNUNET_PIPE) | 1235 | if (fh->type == GNUNET_PIPE) |
1205 | { | 1236 | { |
1237 | #if DEBUG_W32_CYCLES | ||
1238 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1239 | "Polling pipe 0x%x (0x%x)\n", fh, fh->h); | ||
1240 | #endif | ||
1206 | if (!PeekNamedPipe (fh->h, NULL, 0, NULL, &dwBytes, NULL)) | 1241 | if (!PeekNamedPipe (fh->h, NULL, 0, NULL, &dwBytes, NULL)) |
1207 | { | 1242 | { |
1208 | DWORD error_code = GetLastError (); | 1243 | DWORD error_code = GetLastError (); |
@@ -1250,6 +1285,10 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, | |||
1250 | if (efds) | 1285 | if (efds) |
1251 | 1286 | ||
1252 | { | 1287 | { |
1288 | #if DEBUG_W32_CYCLES | ||
1289 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1290 | "Polling efds for broken pipes\n"); | ||
1291 | #endif | ||
1253 | struct GNUNET_CONTAINER_SList_Iterator *i; | 1292 | struct GNUNET_CONTAINER_SList_Iterator *i; |
1254 | for (i = GNUNET_CONTAINER_slist_begin (efds->handles); | 1293 | for (i = GNUNET_CONTAINER_slist_begin (efds->handles); |
1255 | GNUNET_CONTAINER_slist_end (i) != GNUNET_YES; | 1294 | GNUNET_CONTAINER_slist_end (i) != GNUNET_YES; |
@@ -1262,6 +1301,10 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, | |||
1262 | fh = (struct GNUNET_DISK_FileHandle *) GNUNET_CONTAINER_slist_get (i, NULL); | 1301 | fh = (struct GNUNET_DISK_FileHandle *) GNUNET_CONTAINER_slist_get (i, NULL); |
1263 | if (fh->type == GNUNET_PIPE) | 1302 | if (fh->type == GNUNET_PIPE) |
1264 | { | 1303 | { |
1304 | #if DEBUG_W32_CYCLES | ||
1305 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1306 | "Polling pipe 0x%x (0x%x)\n", fh, fh->h); | ||
1307 | #endif | ||
1265 | if (!PeekNamedPipe (fh->h, NULL, 0, NULL, &dwBytes, NULL)) | 1308 | if (!PeekNamedPipe (fh->h, NULL, 0, NULL, &dwBytes, NULL)) |
1266 | 1309 | ||
1267 | { | 1310 | { |
@@ -1313,8 +1356,13 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, | |||
1313 | select_loop_end: | 1356 | select_loop_end: |
1314 | if (retcode == 0) | 1357 | if (retcode == 0) |
1315 | { | 1358 | { |
1359 | /* For pipes, there have been no select() call, so the poll is | ||
1360 | * more likely to miss first time around. For now just don't increase | ||
1361 | * the delay for pipes only. | ||
1362 | */ | ||
1363 | if (nfds != 0) | ||
1364 | cycle_delay = cycle_delay * 2 > 250000 ? 250000 : cycle_delay * 1.4; | ||
1316 | /* Missed an I/O - double the cycle time */ | 1365 | /* Missed an I/O - double the cycle time */ |
1317 | cycle_delay = cycle_delay * 2 > 250 ? 250 : cycle_delay * 1.4; | ||
1318 | #if DEBUG_W32_CYCLES | 1366 | #if DEBUG_W32_CYCLES |
1319 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1367 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1320 | "The cycle missed, increased the delay to %dms\n", cycle_delay); | 1368 | "The cycle missed, increased the delay to %dms\n", cycle_delay); |
@@ -1323,14 +1371,25 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, | |||
1323 | else | 1371 | else |
1324 | { | 1372 | { |
1325 | /* Successfully selected something - decrease the cycle time */ | 1373 | /* Successfully selected something - decrease the cycle time */ |
1326 | cycle_delay -= cycle_delay > 2 ? 2 : 0; | 1374 | /* Minimum is 5 microseconds. Decrease the delay by half, |
1375 | * or by 5000 - whichever is higher. | ||
1376 | */ | ||
1377 | cycle_delay -= cycle_delay > 5000 ? GNUNET_MAX (5000, cycle_delay / 2) : cycle_delay - 5; | ||
1327 | #if DEBUG_W32_CYCLES | 1378 | #if DEBUG_W32_CYCLES |
1328 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1379 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1329 | "The cycle hit, decreased the delay to %dms\n", cycle_delay); | 1380 | "The cycle hit, decreased the delay to %dms\n", cycle_delay); |
1330 | #endif | 1381 | #endif |
1331 | } | 1382 | } |
1332 | if (retcode == 0 && nfds == 0) | 1383 | if (retcode == 0 && nfds == 0) |
1333 | Sleep (GNUNET_MIN (cycle_delay * 1000, limit - GetTickCount ())); | 1384 | { |
1385 | long long diff = limit - GetTickCount (); | ||
1386 | diff = diff > 0 ? diff : 0; | ||
1387 | #if DEBUG_W32_CYCLES | ||
1388 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1389 | "No sockets, sleeping for %d or %d ms\n", cycle_delay / 1000, diff); | ||
1390 | #endif | ||
1391 | Sleep (GNUNET_MIN (cycle_delay / 1000, diff)); | ||
1392 | } | ||
1334 | } | 1393 | } |
1335 | while (retcode == 0 && (ms_total == INFINITE || GetTickCount () < limit)); | 1394 | while (retcode == 0 && (ms_total == INFINITE || GetTickCount () < limit)); |
1336 | 1395 | ||