[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r29111 - gnunet/src/util
From: |
gnunet |
Subject: |
[GNUnet-SVN] r29111 - gnunet/src/util |
Date: |
Sun, 8 Sep 2013 19:37:38 +0200 |
Author: LRN
Date: 2013-09-08 19:37:37 +0200 (Sun, 08 Sep 2013)
New Revision: 29111
Modified:
gnunet/src/util/network.c
Log:
Fix timing problems in *_select() on W32
1) If timeout is < 1ms, round it up to 1ms, because WaitForMultipleObjects()
can't wait for time shorter than 1ms (0ms means "don't wait at all").
2) Read data from the wakeup socket before commanding the select thread to
start selecting. For some reason the socket would be in signalled state
by the time winsock's select() runs, even though we emptied it the last
time. So now we empty it beforehand.
This should prevent us from returning early in some cases.
Modified: gnunet/src/util/network.c
===================================================================
--- gnunet/src/util/network.c 2013-09-08 17:21:33 UTC (rev 29110)
+++ gnunet/src/util/network.c 2013-09-08 17:37:37 UTC (rev 29111)
@@ -1274,7 +1274,8 @@
int i = 0;
int retcode = 0;
- DWORD ms_total = 0;
+ uint64_t mcs_total = 0;
+ DWORD ms_rounded = 0;
int nhandles = 0;
@@ -1383,22 +1384,23 @@
#else
#define SAFE_FD_ISSET(fd, set) (set != NULL && FD_ISSET(fd, set))
- /* calculate how long we need to wait in milliseconds */
+ /* calculate how long we need to wait in microseconds */
if (timeout.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
- ms_total = INFINITE;
+ {
+ mcs_total = INFINITE;
+ ms_rounded = INFINITE;
+ }
else
{
- ms_total = timeout.rel_value_us /
GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us;
- if (timeout.rel_value_us / GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us >
0xFFFFFFFFLL - 1)
- {
- GNUNET_break (0);
- ms_total = 0xFFFFFFFF - 1;
- }
+ mcs_total = timeout.rel_value_us /
GNUNET_TIME_UNIT_MICROSECONDS.rel_value_us;
+ ms_rounded = (DWORD) (mcs_total /
GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us);
+ if (mcs_total > 0 && ms_rounded == 0)
+ ms_rounded = 1;
}
/* select() may be used as a portable way to sleep */
if (!(rfds || wfds || efds))
{
- Sleep (ms_total);
+ Sleep (ms_rounded);
return 0;
}
@@ -1413,9 +1415,9 @@
select_standby_event = CreateEvent (NULL, TRUE, FALSE, NULL);
select_finished_event = CreateEvent (NULL, TRUE, FALSE, NULL);
- select_wakeup_socket = WSASocket (AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL,
0, WSA_FLAG_OVERLAPPED);
+ select_wakeup_socket = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
- select_listening_socket = WSASocket (AF_INET, SOCK_STREAM, IPPROTO_TCP,
NULL, 0, WSA_FLAG_OVERLAPPED);
+ select_listening_socket = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
p = 1;
res = ioctlsocket (select_wakeup_socket, FIONBIO, &p);
@@ -1518,7 +1520,7 @@
/* If our select returned something or is a 0-timed request, then also check
the pipes and get out of here! */
/* Sadly, it means code duplication :( */
- if ((selectret > 0) || (ms_total == 0))
+ if ((selectret > 0) || (mcs_total == 0))
{
/* Read Pipes */
if (rfds && read_handles)
@@ -1781,6 +1783,10 @@
sp.tv = &select_timeout;
}
FD_SET (select_wakeup_socket, &aread);
+ do
+ {
+ i = recv (select_wakeup_socket, (char *) &returnedpos, 1, 0);
+ } while (i == 1);
sp.r = &aread;
sp.w = &awrite;
sp.e = &aexcept;
@@ -1798,17 +1804,17 @@
}
handle_array[nhandles] = NULL;
- LOG (GNUNET_ERROR_TYPE_DEBUG, "nfds: %d, handles: %d, will wait: %llu ms\n",
- nfds, nhandles, (unsigned long long) ms_total);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "nfds: %d, handles: %d, will wait: %llu mcs\n",
+ nfds, nhandles, mcs_total);
if (nhandles)
{
returncode =
- WaitForMultipleObjects (nhandles, handle_array, FALSE, ms_total);
- LOG (GNUNET_ERROR_TYPE_DEBUG, "WaitForMultipleObjects Returned : %d\n",
- returncode);
+ WaitForMultipleObjects (nhandles, handle_array, FALSE, ms_rounded);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "WaitForMultipleObjects Returned : %d\n",
returncode);
}
else if (nfds > 0)
{
+ GNUNET_break (0); /* This branch shouldn't actually be executed...*/
i = (int) WaitForSingleObject (select_finished_event, INFINITE);
returncode = WAIT_TIMEOUT;
}
@@ -1823,11 +1829,11 @@
/* Don't wake up select-thread when delay is 0, it should return
immediately
* and wake up by itself.
*/
- if (ms_total != 0)
+ if (mcs_total != 0)
i = send (select_send_socket, (const char *) &returnedpos, 1, 0);
i = (int) WaitForSingleObject (select_finished_event, INFINITE);
LOG (GNUNET_ERROR_TYPE_DEBUG, "Finished waiting for the select thread: %d
%d\n", i, sp.status);
- if (ms_total != 0)
+ if (mcs_total != 0)
{
do
{
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r29111 - gnunet/src/util,
gnunet <=