/** * Function setting up file descriptors and scheduling task to run * * @param plugin plugin as closure * @param now schedule task in 1ms, regardless of what curl may say * @return GNUNET_SYSERR for hard failure, GNUNET_OK for ok */ static int client_schedule (struct Plugin *plugin, int now) { fd_set rs; fd_set ws; fd_set es; int max; struct GNUNET_NETWORK_FDSet *grs; struct GNUNET_NETWORK_FDSet *gws; long to; CURLMcode mret; struct GNUNET_TIME_Relative timeout; /* Cancel previous scheduled task */ if (plugin->client_perform_task != GNUNET_SCHEDULER_NO_TASK) { GNUNET_SCHEDULER_cancel (plugin->client_perform_task); plugin->client_perform_task = GNUNET_SCHEDULER_NO_TASK; } max = -1; FD_ZERO (&rs); FD_ZERO (&ws); FD_ZERO (&es); mret = curl_multi_fdset (plugin->client_mh, &rs, &ws, &es, &max); if (mret != CURLM_OK) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"), "curl_multi_fdset", __FILE__, __LINE__, curl_multi_strerror (mret)); return GNUNET_SYSERR; } mret = curl_multi_timeout (plugin->client_mh, &to); if (to == -1) timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1); else timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, to); if (now == GNUNET_YES) timeout = GNUNET_TIME_UNIT_MILLISECONDS; if (mret != CURLM_OK) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"), "curl_multi_timeout", __FILE__, __LINE__, curl_multi_strerror (mret)); return GNUNET_SYSERR; } grs = GNUNET_NETWORK_fdset_create (); gws = GNUNET_NETWORK_fdset_create (); GNUNET_NETWORK_fdset_copy_native (grs, &rs, max + 1); GNUNET_NETWORK_fdset_copy_native (gws, &ws, max + 1); plugin->client_perform_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, timeout, grs, gws, &client_run, plugin); GNUNET_NETWORK_fdset_destroy (gws); GNUNET_NETWORK_fdset_destroy (grs); return GNUNET_OK; }
static void mhd_main () { struct GNUNET_NETWORK_FDSet nrs; struct GNUNET_NETWORK_FDSet nws; fd_set rs; fd_set ws; fd_set es; int max_fd; unsigned MHD_LONG_LONG timeout; struct GNUNET_TIME_Relative delay; GNUNET_assert (NULL == mhd_task_id); FD_ZERO (&rs); FD_ZERO (&ws); FD_ZERO (&es); max_fd = -1; GNUNET_assert (MHD_YES == MHD_get_fdset (mhd, &rs, &ws, &es, &max_fd)); if (MHD_YES == MHD_get_timeout (mhd, &timeout)) delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, (unsigned int) timeout); else delay = GNUNET_TIME_UNIT_FOREVER_REL; GNUNET_NETWORK_fdset_copy_native (&nrs, &rs, max_fd + 1); GNUNET_NETWORK_fdset_copy_native (&nws, &ws, max_fd + 1); mhd_task_id = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, delay, &nrs, &nws, &mhd_task, NULL); }
/** * Function that queries MHD's select sets and * starts the task waiting for them. */ static struct GNUNET_SCHEDULER_Task * prepare_daemon (struct MHD_Daemon *daemon_handle) { struct GNUNET_SCHEDULER_Task * ret; fd_set rs; fd_set ws; fd_set es; struct GNUNET_NETWORK_FDSet *wrs; struct GNUNET_NETWORK_FDSet *wws; int max; MHD_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 (); 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.rel_value_us = (uint64_t) timeout * 1000LL; else tv = GNUNET_TIME_UNIT_FOREVER_REL; GNUNET_NETWORK_fdset_copy_native (wrs, &rs, max + 1); GNUNET_NETWORK_fdset_copy_native (wws, &ws, max + 1); ret = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, tv, wrs, wws, &run_daemon, daemon_handle); GNUNET_NETWORK_fdset_destroy (wrs); GNUNET_NETWORK_fdset_destroy (wws); return ret; }
static void curl_main () { fd_set rs; fd_set ws; fd_set es; int max; struct GNUNET_NETWORK_FDSet nrs; struct GNUNET_NETWORK_FDSet nws; struct GNUNET_TIME_Relative delay; long timeout; int running; struct CURLMsg *msg; max = 0; FD_ZERO (&rs); FD_ZERO (&ws); FD_ZERO (&es); curl_multi_perform (multi, &running); if (running == 0) { GNUNET_assert (NULL != (msg = curl_multi_info_read (multi, &running))); if (msg->msg == CURLMSG_DONE) { if (msg->data.result != CURLE_OK) { fprintf (stderr, "%s failed at %s:%d: `%s'\n", "curl_multi_perform", __FILE__, __LINE__, curl_easy_strerror (msg->data.result)); global_ret = 1; } } curl_multi_remove_handle (multi, curl); curl_multi_cleanup (multi); curl_easy_cleanup (curl); curl = NULL; multi = NULL; if (cbc.pos != strlen ("/hello_world")) { GNUNET_break (0); global_ret = 2; } if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world"))) { GNUNET_break (0); global_ret = 3; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download complete, shutting down!\n"); do_shutdown (); return; } GNUNET_assert (CURLM_OK == curl_multi_fdset (multi, &rs, &ws, &es, &max)); if ( (CURLM_OK != curl_multi_timeout (multi, &timeout)) || (-1 == timeout) ) delay = GNUNET_TIME_UNIT_SECONDS; else delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, (unsigned int) timeout); GNUNET_NETWORK_fdset_copy_native (&nrs, &rs, max + 1); GNUNET_NETWORK_fdset_copy_native (&nws, &ws, max + 1); curl_task_id = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, delay, &nrs, &nws, &curl_task, NULL); }