/**
* Our configuration.
*/
-static struct GNUNET_CONFIGURATION_Handle *cfg;
+static const struct GNUNET_CONFIGURATION_Handle *cfg;
/**
* Our scheduler.
*/
static struct GNUNET_SCHEDULER_Handle *sched;
+/**
+ * Our primary task.
+ */
+static GNUNET_SCHEDULER_TaskIdentifier hostlist_task;
+
/**
* Our canonical response.
*/
*/
struct HostSet
{
- size_t size;
+ unsigned int size;
char *data;
};
GNUNET_SCHEDULER_add_delayed (sched,
GNUNET_NO,
GNUNET_SCHEDULER_PRIORITY_IDLE,
- GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
+ GNUNET_SCHEDULER_NO_TASK,
RESPONSE_UPDATE_FREQUENCY,
&update_response,
NULL);
size_t s;
if (peer == NULL)
- finish_response (results);
+ {
+ finish_response (results);
+ return;
+ }
old = results->size;
s = GNUNET_HELLO_size(hello);
if (old + s >= GNUNET_MAX_MALLOC_CHECKED)
}
-
+/**
+ * Hostlist access policy (very permissive, allows everything).
+ */
static int
accept_policy_callback (void *cls,
const struct sockaddr *addr, socklen_t addrlen)
}
+/**
+ * Main request handler.
+ */
static int
access_handler_callback (void *cls,
struct MHD_Connection *connection,
const char *method,
const char *version,
const char *upload_data,
- unsigned int *upload_data_size, void **con_cls)
+ size_t*upload_data_size, void **con_cls)
{
static int dummy;
}
+/**
+ * Function that queries MHD's select sets and
+ * starts the task waiting for them.
+ */
+static void
+prepare_daemon (void);
+
+
+/**
+ * Call MHD to process pending requests and then go back
+ * and schedule the next run.
+ */
+static void
+run_daemon (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ GNUNET_assert (MHD_YES == MHD_run (daemon_handle));
+ prepare_daemon ();
+}
+
+
+/**
+ * Function that queries MHD's select sets and
+ * starts the task waiting for them.
+ */
+static void
+prepare_daemon ()
+{
+ fd_set rs;
+ fd_set ws;
+ fd_set es;
+ struct GNUNET_NETWORK_FDSet *wrs;
+ struct GNUNET_NETWORK_FDSet *wws;
+ struct GNUNET_NETWORK_FDSet *wes;
+ int max;
+ unsigned long long timeout;
+ int haveto;
+ struct GNUNET_TIME_Relative tv;
+
+ FD_ZERO(&rs);
+ FD_ZERO(&ws);
+ FD_ZERO(&es);
+ wrs = GNUNET_NETWORK_fdset_create ();
+ wes = GNUNET_NETWORK_fdset_create ();
+ wws = GNUNET_NETWORK_fdset_create ();
+ max = -1;
+ GNUNET_assert (MHD_YES ==
+ MHD_get_fdset (daemon_handle,
+ &rs,
+ &ws,
+ &es,
+ &max));
+ haveto = MHD_get_timeout (daemon_handle, &timeout);
+ if (haveto == MHD_YES)
+ tv.value = (uint64_t) timeout;
+ else
+ tv = GNUNET_TIME_UNIT_FOREVER_REL;
+ GNUNET_NETWORK_fdset_copy_native (wrs, &rs, max);
+ GNUNET_NETWORK_fdset_copy_native (wws, &ws, max);
+ GNUNET_NETWORK_fdset_copy_native (wes, &es, max);
+ hostlist_task
+ = GNUNET_SCHEDULER_add_select (sched,
+ GNUNET_NO,
+ GNUNET_SCHEDULER_PRIORITY_HIGH,
+ GNUNET_SCHEDULER_NO_TASK,
+ tv,
+ wrs,
+ wws,
+ &run_daemon,
+ NULL);
+ GNUNET_NETWORK_fdset_destroy (wrs);
+ GNUNET_NETWORK_fdset_destroy (wws);
+ GNUNET_NETWORK_fdset_destroy (wes);
+}
+
+
+
/**
* Start server offering our hostlist.
*
* @return GNUNET_OK on success
*/
int
-GNUNET_HOSTLIST_server_start (struct GNUNET_CONFIGURATION_Handle *c,
+GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c,
struct GNUNET_SCHEDULER_Handle *s,
struct GNUNET_STATISTICS_Handle *st)
{
cfg = c;
if (-1 == GNUNET_CONFIGURATION_get_value_number (cfg,
"HOSTLIST",
- "PORT",
+ "HTTPPORT",
&port))
return GNUNET_SYSERR;
- /* FIXME: must use *external* SELECT mode since our
- code is NOT thread safe! Integrate with scheduler! */
- daemon_handle = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_IPv6,
+ daemon_handle = MHD_start_daemon (MHD_USE_IPv6,
(unsigned short) port,
&accept_policy_callback,
NULL,
(unsigned short) port);
return GNUNET_SYSERR;
}
+ prepare_daemon ();
return GNUNET_OK;
}
void
GNUNET_HOSTLIST_server_stop ()
{
+ GNUNET_SCHEDULER_cancel (sched, hostlist_task);
+ hostlist_task = GNUNET_SCHEDULER_NO_TASK;
MHD_stop_daemon (daemon_handle);
daemon_handle = NULL;
}