[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r34982 - gnunet-gtk/src/lib
From: |
gnunet |
Subject: |
[GNUnet-SVN] r34982 - gnunet-gtk/src/lib |
Date: |
Sun, 25 Jan 2015 00:28:13 +0100 |
Author: LRN
Date: 2015-01-25 00:28:13 +0100 (Sun, 25 Jan 2015)
New Revision: 34982
Modified:
gnunet-gtk/src/lib/eventloop.c
Log:
Rewrite GNUnet GTK select
* Separate W32 and non-W32 functions
* W32 function runs g_poll() and gnunet select in separate threads
Modified: gnunet-gtk/src/lib/eventloop.c
===================================================================
--- gnunet-gtk/src/lib/eventloop.c 2015-01-24 23:09:01 UTC (rev 34981)
+++ gnunet-gtk/src/lib/eventloop.c 2015-01-24 23:28:13 UTC (rev 34982)
@@ -33,8 +33,14 @@
*
* TODO: get some statistics, find the maximum number of fds ever
* polled during normal gnunet-gtk operation, and set this to that number.
+ * For non-Windows OSes, that is. For Windows it's always 64, because
+ * that's the limit anyway.
*/
+#ifdef WINDOWS
+#define INITIAL_POLL_ARRAY_SIZE 64
+#else
#define INITIAL_POLL_ARRAY_SIZE 30
+#endif
/**
* Main context for our event loop.
@@ -360,6 +366,284 @@
}
+#ifdef WINDOWS
+/**
+ * FIXME.
+ */
+struct _select_params_gtk
+{
+ /**
+ * Read set.
+ */
+ struct GNUNET_NETWORK_FDSet *rfds;
+
+ /**
+ * Write set.
+ */
+ struct GNUNET_NETWORK_FDSet *wfds;
+
+ /**
+ * Except set.
+ */
+ struct GNUNET_NETWORK_FDSet *efds;
+
+ /**
+ * Timeout for select().
+ */
+ struct GNUNET_TIME_Relative timeout;
+
+ /**
+ * FIXME.
+ */
+ HANDLE event_to_that_wakes_us_up;
+
+ /**
+ * FIXME.
+ */
+ HANDLE event_to_signal_we_woke_up;
+
+ /**
+ * FIXME.
+ */
+ HANDLE event_to_wait_for_a_job;
+
+ /**
+ * Set to return value from select.
+ */
+ int status;
+};
+
+static unsigned __stdcall
+_gnunet_selector_thread (void *p)
+{
+ struct _select_params_gtk *sp = p;
+
+ while (1)
+ {
+ WaitForSingleObject (sp->event_to_wait_for_a_job, INFINITE);
+ ResetEvent (sp->event_to_wait_for_a_job);
+ sp->status = GNUNET_NETWORK_socket_select (sp->rfds, sp->wfds, sp->efds,
sp->timeout);
+ SetEvent (sp->event_to_signal_we_woke_up);
+ }
+ return 0;
+}
+
+static int
+handle_gui_events (struct GNUNET_GTK_MainLoop *ml, gint max_priority, gint
need_gfds)
+{
+ /* Take care of GUI events.
+ * Dispatching the events here will eventually crash the scheduler, must do
this
+ * from within a task (currently we're not in a task, but in a select()
call, remember)
+ * Startup reason is used to pass the scheduler sanity check.
+ */
+ if (NULL == ml->gmc)
+ return GNUNET_NO;
+ if (TRUE ==
+ g_main_context_check (ml->gmc, max_priority,
+ ml->cached_poll_array, need_gfds))
+ {
+ GNUNET_SCHEDULER_add_continuation_with_priority (&dispatch_gtk_task, ml,
+
GNUNET_SCHEDULER_REASON_STARTUP,
+
GNUNET_SCHEDULER_PRIORITY_UI);
+ return GNUNET_YES;
+ }
+ return GNUNET_NO;
+}
+
+
+/**
+ * Replacement for the GNUnet scheduler's "select" that integrates the
+ * Gtk event loop. We run g_poll() in the main thread and run
+ * GNUnet's own select() in a separate thread in parallel.
+ * Then we process the Gtk events (by adding a task to do so to the GNUnet
+ * scheduler), and, if applicable, return the GNUnet-scheduler events back
+ * to GNUnet.
+ *
+ * @param cls the 'struct GNUNET_GTK_MainLoop'
+ * @param rfds set of sockets to be checked for readability
+ * @param wfds set of sockets to be checked for writability
+ * @param efds set of sockets to be checked for exceptions
+ * @param timeout relative value when to return
+ * @return number of selected sockets, GNUNET_SYSERR on error
+ */
+static int
+gnunet_gtk_select (void *cls,
+ struct GNUNET_NETWORK_FDSet *rfds,
+ struct GNUNET_NETWORK_FDSet *wfds,
+ struct GNUNET_NETWORK_FDSet *efds,
+ const struct GNUNET_TIME_Relative timeout)
+{
+ struct GNUNET_GTK_MainLoop *ml = cls;
+ int gnunet_select_result;
+ struct GNUNET_TIME_Relative timeout_from_delay;
+ gint delay;
+ gint need_gfds;
+ gint max_priority;
+ gint g_poll_result;
+ DWORD wait_result;
+
+ static struct GNUNET_NETWORK_FDSet *standin_rfds;
+ static HANDLE wakeup_event_for_gnunet;
+ static HANDLE gnunet_woke_up_event;
+ static HANDLE gnunet_selector_thread_job_event;
+ static struct GNUNET_DISK_FileHandle *wakeup_event_for_gnunet_fh;
+ static struct _select_params_gtk *sp;
+
+ /* To be safe, we do g_poll in the main thread (MSDN does mention
+ * something about message queue being per-thread, and g_poll does
+ * wait for messages), unless glib main loop is not running,
+ * in which case we just use gnunet select right here.
+ */
+ static HANDLE gnunet_select_subthread;
+
+ static gsize initialized = 0;
+
+ if (ml->gml == NULL || TRUE != g_main_loop_is_running (ml->gml))
+ return GNUNET_NETWORK_socket_select (rfds, wfds, efds, timeout);
+
+ if (g_once_init_enter (&initialized))
+ {
+ wakeup_event_for_gnunet = CreateEvent (NULL, TRUE, FALSE, NULL);
+ gnunet_woke_up_event = CreateEvent (NULL, TRUE, FALSE, NULL);
+ standin_rfds = GNUNET_NETWORK_fdset_create ();
+ wakeup_event_for_gnunet_fh = GNUNET_DISK_get_handle_from_w32_handle
(wakeup_event_for_gnunet);
+ gnunet_selector_thread_job_event = CreateEvent (NULL, TRUE, FALSE, NULL);
+ sp = GNUNET_new (struct _select_params_gtk);
+
+ sp->event_to_signal_we_woke_up = gnunet_woke_up_event;
+ sp->event_to_that_wakes_us_up = wakeup_event_for_gnunet;
+ sp->event_to_wait_for_a_job = gnunet_selector_thread_job_event;
+
+ gnunet_select_subthread = (HANDLE) _beginthreadex (NULL, 0,
_gnunet_selector_thread, sp, 0, NULL);
+
+ g_once_init_leave (&initialized, 1);
+ }
+
+ if (wakeup_event_for_gnunet == NULL ||
+ gnunet_woke_up_event == NULL ||
+ gnunet_select_subthread == NULL ||
+ wakeup_event_for_gnunet_fh == NULL ||
+ gnunet_selector_thread_job_event == NULL)
+ {
+ GNUNET_break (0);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "%s", _("Failed to initialize GNUnet-GTK select\n"));
+ return GNUNET_SYSERR;
+ }
+
+ timeout_from_delay = GNUNET_TIME_UNIT_ZERO;
+ /* Optimization hack: assume that at least one of the fds
+ * is not NULL and not empty.
+ */
+ gnunet_select_result = GNUNET_NETWORK_socket_select (rfds, wfds, efds,
timeout_from_delay);
+ if (gnunet_select_result < 0)
+ return gnunet_select_result;
+
+ if (ml->cached_poll_array_size == 0)
+ resize_cached_poll_array (ml, INITIAL_POLL_ARRAY_SIZE);
+
+ delay = INT_MAX;
+ need_gfds = -1;
+ if (NULL != ml->gmc)
+ {
+ g_main_context_prepare (ml->gmc, &max_priority);
+ need_gfds =
+ g_main_context_query (ml->gmc, max_priority, &delay,
+ ml->cached_poll_array,
+ ml->cached_poll_array_size);
+ if (ml->cached_poll_array_size < need_gfds + 1)
+ {
+ GNUNET_break (0);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Ran out of handle space - g_poll() needs %d handles, has %d!\n"),
+ need_gfds + 1, ml->cached_poll_array_size);
+ return GNUNET_SYSERR;
+ }
+ }
+ if (timeout.rel_value_us != GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
+ {
+ if (delay >= 0)
+ delay =
+ GNUNET_MIN (timeout.rel_value_us /
+ GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us, delay);
+ else
+ delay = timeout.rel_value_us /
GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us;
+ }
+
+ g_poll_result = g_poll (ml->cached_poll_array, need_gfds, 0);
+ if (g_poll_result < 0)
+ {
+ GNUNET_break (0);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "g_poll() returned %d\n",
+ g_poll_result);
+ return GNUNET_SYSERR;
+ }
+ g_poll_result = (GNUNET_YES == handle_gui_events (ml, max_priority,
need_gfds)) ? 1 : 0;
+
+ if ((gnunet_select_result > 0) ||
+ (g_poll_result > 0) ||
+ (delay == 0))
+ {
+ return gnunet_select_result + g_poll_result;
+ }
+
+ if (rfds == NULL)
+ rfds = standin_rfds;
+
+ ResetEvent (wakeup_event_for_gnunet);
+ ResetEvent (gnunet_woke_up_event);
+
+ GNUNET_NETWORK_fdset_handle_set_first (rfds, wakeup_event_for_gnunet_fh);
+
+ sp->status = 0;
+ /* Optimization hack: assume that at least one of the fds
+ * is not NULL and not empty.
+ */
+ sp->rfds = rfds;
+ sp->wfds = wfds;
+ sp->efds = efds;
+
+ sp->timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS,
delay);
+ ml->cached_poll_array[need_gfds].fd = (intptr_t) gnunet_woke_up_event;
+ ml->cached_poll_array[need_gfds].events = G_IO_IN;
+
+ /* Wakes up the gnunet selector thread */
+ SetEvent (gnunet_selector_thread_job_event);
+
+ /* During this call, if gnunet select threads wakes up first,
+ * it will set gnunet_woke_up_event, waking us up.
+ */
+ g_poll_result = g_poll (ml->cached_poll_array, need_gfds + 1, delay);
+
+ SetEvent (wakeup_event_for_gnunet);
+
+ wait_result = WaitForSingleObject (gnunet_woke_up_event, INFINITE);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Finished waiting for the gnunet select thread: %lu %d\n",
+ wait_result,
+ sp->status);
+
+ g_poll_result = (GNUNET_YES == handle_gui_events (ml, max_priority,
need_gfds)) ? 1 : 0;
+
+ if (-1 == sp->status)
+ {
+ return GNUNET_SYSERR;
+ }
+
+ if (GNUNET_NETWORK_fdset_handle_isset (rfds, wakeup_event_for_gnunet_fh))
+ sp->status -= 1;
+
+ if (-1 == sp->status)
+ {
+ GNUNET_break (0);
+ }
+
+ return sp->status + g_poll_result;
+}
+
+#else
+
#ifndef FD_COPY
#define FD_COPY(s, d) (memcpy ((d), (s), sizeof (fd_set)))
#endif
@@ -398,18 +682,6 @@
int result = 0;
gint max_priority;
-#if WINDOWS
- int pre_ret = 0;
- int sock_read = 0;
- int sock_write = 0;
- int sock_err = 0;
- int socks;
- int always_ready_write_fd = -1;
- int select_ret = 0;
- int read_handles = 0;
- DWORD waitstatus;
-#endif
-
if (ml->gml == NULL || TRUE != g_main_loop_is_running (ml->gml))
return GNUNET_NETWORK_socket_select (rfds, wfds, efds, timeout);
if (NULL != rfds)
@@ -425,15 +697,6 @@
else
FD_ZERO (&aexcept);
-#if WINDOWS
- ResetEvent (ml->hEventRead);
- ResetEvent (ml->hEventWrite);
- ResetEvent (ml->hEventException);
- GNUNET_CONTAINER_slist_clear (ml->handles_read);
- GNUNET_CONTAINER_slist_clear (ml->handles_write);
- GNUNET_CONTAINER_slist_clear (ml->handles_except);
-#endif
-
max_nfds = -1;
if (rfds != NULL)
max_nfds = GNUNET_MAX (max_nfds, rfds->nsds);
@@ -445,7 +708,6 @@
if (ml->cached_poll_array_size == 0)
resize_cached_poll_array (ml, INITIAL_POLL_ARRAY_SIZE);
-#if !WINDOWS
fd_counter = 0;
for (i = 0; i < max_nfds; i++)
{
@@ -465,185 +727,7 @@
(isset[2] ? G_IO_ERR : 0);
fd_counter++;
}
-#else
- {
- struct GNUNET_CONTAINER_SList_Iterator t;
- fd_counter = 0;
- /* We might overshoot a little, but that won't hurt very much */
- int need_nfds =
- (rfds->sds.fd_count + rfds->sds.fd_count + rfds->sds.fd_count >
- 0 ? 3 : 0) + (rfds ==
- NULL ? 0 : GNUNET_CONTAINER_slist_count (rfds->
- handles)) +
- (wfds == NULL ? 0 : 1) + 1;
- if (need_nfds >= ml->cached_poll_array_size)
- resize_cached_poll_array (ml, need_nfds * 2);
- /* Since there are also gmainloop's own fds, just need_nfds won't be
- * enough, so make it twice as long.
- */
- if (ml->read_array_length < GNUNET_CONTAINER_slist_count (rfds->handles))
- {
- ml->read_array =
- GNUNET_realloc (ml->read_array,
- GNUNET_CONTAINER_slist_count (rfds->handles) *
- sizeof (struct GNUNET_DISK_FileHandle *));
- ml->read_array_length = GNUNET_CONTAINER_slist_count (rfds->handles);
- }
- if (rfds != NULL)
- {
- for (t = GNUNET_CONTAINER_slist_begin (rfds->handles), i = 0;
- GNUNET_CONTAINER_slist_end (&t) != GNUNET_YES;
- GNUNET_CONTAINER_slist_next (&t), i += 1)
- {
- struct GNUNET_DISK_FileHandle *fh =
- GNUNET_CONTAINER_slist_get (&t, NULL);
- if (fh->type == GNUNET_DISK_HANLDE_TYPE_PIPE)
- {
- if (!ReadFile (fh->h, NULL, 0, NULL, fh->oOverlapRead))
- {
- DWORD error_code = GetLastError ();
-
- if (error_code == ERROR_IO_PENDING)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Adding the pipe's 0x%x overlapped event to the
array as %d\n",
- fh->h, fd_counter);
- ml->cached_poll_array[fd_counter].fd =
- (intptr_t) fh->oOverlapRead->hEvent;
- /* On W32 .events makes no sense - g_poll will just OR its
- * contents into .revents when the .fd event fires.
- * So we'll use it in the way that suits us the best.
- */
- ml->cached_poll_array[fd_counter].events = G_IO_IN;
- fd_counter += 1;
- ml->read_array[read_handles] = fh;
- read_handles += 1;
- }
- else
- {
- ml->cached_poll_array[fd_counter].fd =
- (intptr_t) ml->hEventReadReady;
- ml->cached_poll_array[fd_counter].events = G_IO_HUP;
- fd_counter += 1;
- ml->read_array[read_handles] = fh;
- read_handles += 1;
- }
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Adding the read ready event to the array as %d\n",
- fd_counter);
- ml->cached_poll_array[fd_counter].fd =
- (intptr_t) ml->hEventReadReady;
- ml->cached_poll_array[fd_counter].events = G_IO_IN;
- fd_counter += 1;
- ml->read_array[read_handles] = fh;
- read_handles += 1;
- }
- }
- else
- {
- GNUNET_CONTAINER_slist_add (ml->handles_read,
-
GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT,
- fh,
- sizeof (struct GNUNET_DISK_FileHandle));
- pre_ret++;
- }
- }
- }
- if ((wfds != NULL) && (GNUNET_CONTAINER_slist_count (wfds->handles) > 0))
- {
- ml->cached_poll_array[fd_counter].fd = (intptr_t) ml->hEventPipeWrite;
- ml->cached_poll_array[fd_counter].events = G_IO_OUT;
- always_ready_write_fd = fd_counter;
- fd_counter += 1;
- }
- if (efds != NULL)
- {
- for (t = GNUNET_CONTAINER_slist_begin (efds->handles), i = 0;
- GNUNET_CONTAINER_slist_end (&t) != GNUNET_YES;
- GNUNET_CONTAINER_slist_next (&t), i += 1)
- {
- struct GNUNET_DISK_FileHandle *fh =
- GNUNET_CONTAINER_slist_get (&t, NULL);
-
- DWORD dwBytes;
-
- if (fh->type == GNUNET_DISK_HANLDE_TYPE_PIPE)
- {
- if (!PeekNamedPipe (fh->h, NULL, 0, NULL, &dwBytes, NULL))
- {
- GNUNET_CONTAINER_slist_add (ml->handles_except,
-
GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT,
- fh,
- sizeof (struct
GNUNET_DISK_FileHandle));
- pre_ret++;
- }
- }
- }
- }
-
- if ((rfds != NULL) && (rfds->sds.fd_count > 0))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Adding the socket read event to the array as %d\n",
- fd_counter);
- ml->cached_poll_array[fd_counter].fd = (intptr_t) ml->hEventRead;
- ml->cached_poll_array[fd_counter].events = G_IO_IN;
- for (i = 0; i < rfds->sds.fd_count; i++)
- WSAEventSelect (rfds->sds.fd_array[i], ml->hEventRead,
- FD_ACCEPT | FD_READ | FD_CLOSE);
- fd_counter += 1;
- sock_read = rfds->sds.fd_count;
- }
- if ((wfds != NULL) && (wfds->sds.fd_count > 0))
- {
- int wakeup = 0;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Adding the socket write event to the array as %d\n",
- fd_counter);
- ml->cached_poll_array[fd_counter].fd = (intptr_t) ml->hEventWrite;
- ml->cached_poll_array[fd_counter].events = G_IO_OUT;
- for (ui = 0; ui < wfds->sds.fd_count; ui++)
- {
- DWORD error;
- int status;
-
- status = send (wfds->sds.fd_array[ui], NULL, 0, 0);
- error = GetLastError ();
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "pre-send to the socket %u returned %d (%u)\n", ui, status,
- error);
- if (status == 0 || (error != WSAEWOULDBLOCK && error != WSAENOTCONN))
- wakeup = 1;
- WSAEventSelect (wfds->sds.fd_array[ui], ml->hEventWrite,
- FD_WRITE | FD_CONNECT | FD_CLOSE);
- }
- if (wakeup)
- SetEvent (ml->hEventWrite);
- fd_counter += 1;
- sock_write = wfds->sds.fd_count;
- }
- if ((efds != NULL) && (efds->sds.fd_count > 0))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Adding the socket error event to the array as %d\n",
- fd_counter);
- ml->cached_poll_array[fd_counter].fd = (intptr_t) ml->hEventException;
- ml->cached_poll_array[fd_counter].events = G_IO_ERR;
- for (ui = 0; ui < efds->sds.fd_count; ui++)
- WSAEventSelect (efds->sds.fd_array[ui], ml->hEventException,
- FD_OOB | FD_CLOSE);
- fd_counter++;
- sock_err = efds->sds.fd_count;
- }
- }
- socks = sock_read + sock_write + sock_err;
-#endif
-
/* combine with Gtk events */
if (NULL != ml->gmc)
{
@@ -669,15 +753,6 @@
delay = timeout.rel_value_us /
GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us;
}
-#if WINDOWS
- if (pre_ret > 0)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "pre_ret is %d, setting delay to 0\n",
- pre_ret);
- delay = 0;
- }
-#endif
-
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"We have %d of our FDs and %d of GMC ones, going to wait
%6dms\n",
fd_counter, need_gfds, delay);
@@ -701,7 +776,6 @@
GNUNET_SCHEDULER_PRIORITY_UI);
}
/* Now map back GNUnet scheduler events ... */
-#if !WINDOWS
if (NULL != rfds)
GNUNET_NETWORK_fdset_zero (rfds);
if (NULL != wfds)
@@ -732,153 +806,10 @@
if (set)
result++;
}
-#else
- if (socks > 0)
- {
- struct timeval tvslice;
-
- tvslice.tv_sec = 0;
- tvslice.tv_usec = 0;
- select_ret = select (max_nfds, &aread, &awrite, &aexcept, &tvslice);
- if (select_ret == -1)
- select_ret = 0;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "select() returned %d\n", select_ret);
- }
- if (always_ready_write_fd >= 0 &&
- ml->cached_poll_array[always_ready_write_fd].revents & G_IO_OUT)
- {
- GNUNET_CONTAINER_slist_append (ml->handles_write, wfds->handles);
- result += GNUNET_CONTAINER_slist_count (ml->handles_write);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Added write pipe\n");
- }
- for (i = 0; i < read_handles; i++)
- {
- DWORD error;
- BOOL bret;
-
- if (!(ml->cached_poll_array[i].revents & (G_IO_IN | G_IO_HUP | G_IO_ERR)))
- continue;
- SetLastError (0);
- waitstatus = 0;
- bret =
- PeekNamedPipe (ml->read_array[i]->h, NULL, 0, NULL, &waitstatus, NULL);
- error = GetLastError ();
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Peek at read pipe %d (0x%x) returned %d (%d bytes available)
GLE %u\n",
- i, ml->read_array[i]->h, bret, waitstatus, error);
- if (bret == 0 || (ml->cached_poll_array[i].revents & G_IO_ERR))
- {
- if (efds != NULL)
- {
- struct GNUNET_CONTAINER_SList_Iterator t;
-
- for (t = GNUNET_CONTAINER_slist_begin (efds->handles), i = 0;
- GNUNET_CONTAINER_slist_end (&t) != GNUNET_YES;
- GNUNET_CONTAINER_slist_next (&t), i += 1)
- {
- struct GNUNET_DISK_FileHandle *fh =
- GNUNET_CONTAINER_slist_get (&t, NULL);
- if (fh == ml->read_array[i])
- {
- GNUNET_CONTAINER_slist_add (ml->handles_except,
-
GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT,
- fh,
- sizeof (struct
GNUNET_DISK_FileHandle));
- break;
- }
- }
- }
- }
- else if (waitstatus <= 0)
- continue;
- GNUNET_CONTAINER_slist_add (ml->handles_read,
- GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT,
- ml->read_array[i],
- sizeof (struct GNUNET_DISK_FileHandle));
- result += 1;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Added read Pipe 0x%x (0x%x)\n",
- ml->read_array[i], ml->read_array[i]->h);
- }
- waitstatus = WaitForSingleObject (ml->hEventWrite, 0);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Wait for the write event returned
%d\n",
- waitstatus);
- if (waitstatus == WAIT_OBJECT_0)
- {
- for (ui = 0; ui < wfds->sds.fd_count; ui++)
- {
- DWORD error;
- int status;
- int so_error = 0;
- int sizeof_so_error = sizeof (so_error);
- int gso_result = getsockopt (wfds->sds.fd_array[ui],
- SOL_SOCKET, SO_ERROR,
- (char *) &so_error, &sizeof_so_error);
-
- status = send (wfds->sds.fd_array[ui], NULL, 0, 0);
- error = GetLastError ();
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "send to the socket %u returned %d (%u)\n", ui, status,
- error);
- if (status == 0 || (error != WSAEWOULDBLOCK && error != WSAENOTCONN) ||
- (status == -1 && gso_result == 0 && error == WSAENOTCONN &&
- so_error == WSAECONNREFUSED))
- {
- FD_SET (wfds->sds.fd_array[ui], &awrite);
- result += 1;
- }
- }
- }
- if (rfds)
- {
- struct GNUNET_CONTAINER_SList_Iterator t;
-
- for (ui = 0; ui < rfds->sds.fd_count; ui++)
- WSAEventSelect (rfds->sds.fd_array[ui], ml->hEventRead, 0);
- for (t = GNUNET_CONTAINER_slist_begin (rfds->handles);
- GNUNET_CONTAINER_slist_end (&t) != GNUNET_YES;
- GNUNET_CONTAINER_slist_next (&t))
- {
- struct GNUNET_DISK_FileHandle *fh = GNUNET_CONTAINER_slist_get (&t,
NULL);
-
- if (fh->type == GNUNET_DISK_HANLDE_TYPE_PIPE)
- CancelIo (fh->h);
- }
- GNUNET_NETWORK_fdset_zero (rfds);
- if (select_ret != -1 && socks > 0)
- GNUNET_NETWORK_fdset_copy_native (rfds, &aread, select_ret);
- GNUNET_CONTAINER_slist_append (rfds->handles, ml->handles_read);
- }
- if (wfds)
- {
- for (ui = 0; ui < wfds->sds.fd_count; ui++)
- WSAEventSelect (wfds->sds.fd_array[ui], ml->hEventWrite, 0);
- GNUNET_NETWORK_fdset_zero (wfds);
- if (select_ret != -1 && socks > 0)
- GNUNET_NETWORK_fdset_copy_native (wfds, &awrite, select_ret);
- GNUNET_CONTAINER_slist_append (wfds->handles, ml->handles_write);
- }
- if (efds)
- {
- for (ui = 0; ui < efds->sds.fd_count; ui++)
- WSAEventSelect (efds->sds.fd_array[ui], ml->hEventException, 0);
- GNUNET_NETWORK_fdset_zero (efds);
- if (select_ret != -1 && socks > 0)
- GNUNET_NETWORK_fdset_copy_native (efds, &aexcept, select_ret);
- GNUNET_CONTAINER_slist_append (efds->handles, ml->handles_except);
- result += GNUNET_CONTAINER_slist_count (ml->handles_except);
- }
- if (fd_counter > 0)
- /* This is not accurate (select_ret counts write-ready sockets,
- * and result does as well. Anything out there actually cares
- * about this?
- */
- result = select_ret + result;
- else
- result = 0;
-#endif
return result;
}
+#endif
/**
* Actual main function run right after GNUnet's scheduler
@@ -944,18 +875,6 @@
ml->cfgfile = GNUNET_strdup (cfgfile);
ml->argc = argc;
ml->argv = args;
-#if WINDOWS
- ml->hEventRead = CreateEvent (NULL, TRUE, FALSE, NULL);
- ml->hEventReadReady = CreateEvent (NULL, TRUE, TRUE, NULL);
- ml->hEventWrite = CreateEvent (NULL, TRUE, FALSE, NULL);
- ml->hEventException = CreateEvent (NULL, TRUE, FALSE, NULL);
- ml->hEventPipeWrite = CreateEvent (NULL, TRUE, TRUE, NULL);
- ml->handles_read = GNUNET_CONTAINER_slist_create ();
- ml->handles_write = GNUNET_CONTAINER_slist_create ();
- ml->handles_except = GNUNET_CONTAINER_slist_create ();
- ml->read_array = NULL;
- ml->read_array_length = 0;
-#endif
/* start the Gtk event loop */
GNUNET_assert (TRUE == g_main_context_acquire (ml->gmc));
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r34982 - gnunet-gtk/src/lib,
gnunet <=