/** * Run the MHD external event loop using select. * * @param daemon daemon to run it for */ static void run_mhd_epoll_loop (struct MHD_Daemon *daemon) { const union MHD_DaemonInfo *di; MHD_socket ep; fd_set rs; MHD_UNSIGNED_LONG_LONG to; struct timeval tv; di = MHD_get_daemon_info (daemon, MHD_DAEMON_INFO_EPOLL_FD); ep = di->listen_fd; while (! done) { FD_ZERO (&rs); to = 1000; FD_SET (ep, &rs); (void) MHD_get_timeout (daemon, &to); if (1000 < to) to = 1000; tv.tv_sec = to / 1000; tv.tv_usec = 1000 * (to % 1000); select (ep + 1, &rs, NULL, NULL, &tv); MHD_run (daemon); } }
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); }
/** * Call with the port number as the only argument. * Never terminates (other than by signals, such as CTRL-C). */ int main (int argc, char *const *argv) { struct MHD_Daemon *d; struct timeval tv; struct timeval *tvp; fd_set rs; fd_set ws; fd_set es; int max; MHD_UNSIGNED_LONG_LONG mhd_timeout; if (argc != 2) { printf ("%s PORT\n", argv[0]); return 1; } /* initialize PRNG */ srand ((unsigned int) time (NULL)); d = MHD_start_daemon (MHD_USE_DEBUG, atoi (argv[1]), NULL, NULL, &create_response, NULL, MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 15, MHD_OPTION_NOTIFY_COMPLETED, &request_completed_callback, NULL, MHD_OPTION_END); if (NULL == d) return 1; while (1) { expire_sessions (); max = 0; FD_ZERO (&rs); FD_ZERO (&ws); FD_ZERO (&es); if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max)) break; /* fatal internal error */ if (MHD_get_timeout (d, &mhd_timeout) == MHD_YES) { tv.tv_sec = mhd_timeout / 1000; tv.tv_usec = (mhd_timeout - (tv.tv_sec * 1000)) * 1000; tvp = &tv; } else tvp = NULL; if (-1 == select (max + 1, &rs, &ws, &es, tvp)) { if (EINTR != errno) fprintf (stderr, "Aborting due to error during select: %s\n", strerror (errno)); break; } MHD_run (d); } MHD_stop_daemon (d); return 0; }
static int testExternalGet (int port) { struct MHD_Daemon *d; pid_t pid; fd_set rs; fd_set ws; fd_set es; MHD_socket max; struct timeval tv; MHD_UNSIGNED_LONG_LONG tt; int tret; d = MHD_start_daemon (MHD_USE_DEBUG, port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END); if (d == NULL) return 256; start_timer (); pid = do_gets (port); while (0 == waitpid (pid, NULL, WNOHANG)) { max = 0; FD_ZERO (&rs); FD_ZERO (&ws); FD_ZERO (&es); if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max)) { MHD_stop_daemon (d); return 4096; } tret = MHD_get_timeout (d, &tt); if (MHD_YES != tret) tt = 1; tv.tv_sec = tt / 1000; tv.tv_usec = 1000 * (tt % 1000); if (-1 == select (max + 1, &rs, &ws, &es, &tv)) { if (EINTR == errno) continue; fprintf (stderr, "select failed: %s\n", strerror (errno)); break; } MHD_run (d); } stop ("external select"); MHD_stop_daemon (d); return 0; }
int main (int argc, char *const *argv) { struct MHD_Daemon *d; time_t end; time_t t; struct timeval tv; fd_set rs; fd_set ws; fd_set es; int max; unsigned MHD_LONG_LONG mhd_timeout; if (argc != 3) { printf ("%s PORT SECONDS-TO-RUN\n", argv[0]); return 1; } d = MHD_start_daemon (MHD_USE_DEBUG, atoi (argv[1]), NULL, NULL, &ahc_echo, PAGE, MHD_OPTION_END); if (d == NULL) return 1; end = time (NULL) + atoi (argv[2]); while ((t = time (NULL)) < end) { tv.tv_sec = end - t; tv.tv_usec = 0; max = 0; FD_ZERO (&rs); FD_ZERO (&ws); FD_ZERO (&es); if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max)) break; /* fatal internal error */ if (MHD_get_timeout (d, &mhd_timeout) == MHD_YES) { if (tv.tv_sec * 1000 < mhd_timeout) { tv.tv_sec = mhd_timeout / 1000; tv.tv_usec = (mhd_timeout - (tv.tv_sec * 1000)) * 1000; } } select (max + 1, &rs, &ws, &es, &tv); MHD_run (d); } MHD_stop_daemon (d); return 0; }
/** * Run the MHD external event loop using select. * * @param daemon daemon to run it for */ static void run_mhd_select_loop (struct MHD_Daemon *daemon) { fd_set rs; fd_set ws; fd_set es; MHD_socket max_fd; MHD_UNSIGNED_LONG_LONG to; struct timeval tv; while (! done) { FD_ZERO (&rs); FD_ZERO (&ws); FD_ZERO (&es); max_fd = -1; to = 1000; if (MHD_YES != MHD_get_fdset (daemon, &rs, &ws, &es, &max_fd)) abort (); (void) MHD_get_timeout (daemon, &to); if (1000 < to) to = 1000; tv.tv_sec = to / 1000; tv.tv_usec = 1000 * (to % 1000); if (0 > MHD_SYS_select_ (max_fd + 1, &rs, &ws, &es, &tv)) abort (); MHD_run_from_select (daemon, &rs, &ws, &es); } }
void WebServer::run() { expireSessions (); max = 0; FD_ZERO (&rs); FD_ZERO (&ws); FD_ZERO (&es); if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max)) return; /* fatal internal error */ if (MHD_get_timeout (d, &mhd_timeout) == MHD_YES) { tv.tv_sec = mhd_timeout / 1000; tv.tv_usec = (mhd_timeout - (tv.tv_sec * 1000)) * 1000; tvp = &tv; } else tvp = NULL; select (max + 1, &rs, &ws, &es, tvp); MHD_run (d); }
/** * 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 int testExternalPost () { struct MHD_Daemon *d; CURL *c; char buf[2048]; struct CBC cbc; CURLM *multi; CURLMcode mret; fd_set rs; fd_set ws; fd_set es; MHD_socket max; int running; struct CURLMsg *msg; time_t start; struct timeval tv; int i; unsigned long long timeout; long ctimeout; char url[1024]; multi = NULL; cbc.buf = buf; cbc.size = 2048; cbc.pos = 0; d = MHD_start_daemon (MHD_USE_DEBUG, 1082, NULL, NULL, &ahc_echo, NULL, MHD_OPTION_END); if (d == NULL) return 256; multi = curl_multi_init (); if (multi == NULL) { MHD_stop_daemon (d); return 512; } for (i = 0; i < LOOPCOUNT; i++) { if (99 == i % 100) fprintf (stderr, "."); c = curl_easy_init (); cbc.pos = 0; buf[0] = '\0'; sprintf (url, "http://127.0.0.1:1082/hw%d", i); curl_easy_setopt (c, CURLOPT_URL, url); curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer); curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc); curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA); curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA)); curl_easy_setopt (c, CURLOPT_POST, 1L); curl_easy_setopt (c, CURLOPT_FAILONERROR, 1); curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L); if (oneone) curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); else curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L); // NOTE: use of CONNECTTIMEOUT without also // setting NOSIGNAL results in really weird // crashes on my system! curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1); mret = curl_multi_add_handle (multi, c); if (mret != CURLM_OK) { curl_multi_cleanup (multi); curl_easy_cleanup (c); MHD_stop_daemon (d); return 1024; } start = time (NULL); while ((time (NULL) - start < 5) && (multi != NULL)) { max = 0; FD_ZERO (&rs); FD_ZERO (&ws); FD_ZERO (&es); while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform (multi, &running)); mret = curl_multi_fdset (multi, &rs, &ws, &es, &max); if (mret != CURLM_OK) { curl_multi_remove_handle (multi, c); curl_multi_cleanup (multi); curl_easy_cleanup (c); MHD_stop_daemon (d); return 2048; } if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max)) { curl_multi_remove_handle (multi, c); curl_multi_cleanup (multi); curl_easy_cleanup (c); MHD_stop_daemon (d); return 4096; } if (MHD_NO == MHD_get_timeout (d, &timeout)) timeout = 100; /* 100ms == INFTY -- CURL bug... */ if ((CURLM_OK == curl_multi_timeout (multi, &ctimeout)) && (ctimeout < timeout) && (ctimeout >= 0)) timeout = ctimeout; if ( (c == NULL) || (running == 0) ) timeout = 0; /* terminate quickly... */ tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout % 1000) * 1000; if (-1 == select (max + 1, &rs, &ws, &es, &tv)) { if (EINTR == errno) continue; fprintf (stderr, "select failed: %s\n", strerror (errno)); break; } while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform (multi, &running)); if (running == 0) { msg = curl_multi_info_read (multi, &running); if (msg == NULL) break; if (msg->msg == CURLMSG_DONE) { if (msg->data.result != CURLE_OK) printf ("%s failed at %s:%d: `%s'\n", "curl_multi_perform", __FILE__, __LINE__, curl_easy_strerror (msg->data.result)); curl_multi_remove_handle (multi, c); curl_easy_cleanup (c); c = NULL; } } MHD_run (d); } if (c != NULL) { curl_multi_remove_handle (multi, c); curl_easy_cleanup (c); } if ((buf[0] != 'O') || (buf[1] != 'K')) { curl_multi_cleanup (multi); MHD_stop_daemon (d); return 8192; } } curl_multi_cleanup (multi); MHD_stop_daemon (d); if (LOOPCOUNT >= 99) fprintf (stderr, "\n"); return 0; }
static int testExternalPost () { struct MHD_Daemon *d; CURL *c; char buf[2048]; struct CBC cbc; CURLM *multi; CURLMcode mret; fd_set rs; fd_set ws; fd_set es; MHD_socket maxsock; #ifdef MHD_WINSOCK_SOCKETS int maxposixs; /* Max socket number unused on W32 */ #else /* MHD_POSIX_SOCKETS */ #define maxposixs maxsock #endif /* MHD_POSIX_SOCKETS */ int running; struct CURLMsg *msg; time_t start; struct timeval tv; int i; unsigned long long timeout; long ctimeout; char url[1024]; int port; if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT)) port = 0; else { port = 1353; if (oneone) port += 10; } multi = NULL; cbc.buf = buf; cbc.size = 2048; cbc.pos = 0; d = MHD_start_daemon (MHD_USE_ERROR_LOG, port, NULL, NULL, &ahc_echo, NULL, MHD_OPTION_END); if (d == NULL) return 256; if (0 == port) { const union MHD_DaemonInfo *dinfo; dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT); if (NULL == dinfo || 0 == dinfo->port) { MHD_stop_daemon (d); return 32; } port = (int)dinfo->port; } multi = curl_multi_init (); if (multi == NULL) { MHD_stop_daemon (d); return 512; } for (i = 0; i < LOOPCOUNT; i++) { if (99 == i % 100) fprintf (stderr, "."); c = curl_easy_init (); cbc.pos = 0; buf[0] = '\0'; snprintf (url, sizeof (url), "http://127.0.0.1:%d/hw%d", port, i); curl_easy_setopt (c, CURLOPT_URL, url); curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer); curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc); curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA); curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA)); curl_easy_setopt (c, CURLOPT_POST, 1L); curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L); curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L); if (oneone) curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); else curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L); /* NOTE: use of CONNECTTIMEOUT without also * setting NOSIGNAL results in really weird * crashes on my system! */ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L); mret = curl_multi_add_handle (multi, c); if (mret != CURLM_OK) { curl_multi_cleanup (multi); curl_easy_cleanup (c); MHD_stop_daemon (d); return 1024; } start = time (NULL); while ((time (NULL) - start < 5) && (multi != NULL)) { maxsock = MHD_INVALID_SOCKET; maxposixs = -1; FD_ZERO (&rs); FD_ZERO (&ws); FD_ZERO (&es); while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform (multi, &running)); mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs); if (mret != CURLM_OK) { curl_multi_remove_handle (multi, c); curl_multi_cleanup (multi); curl_easy_cleanup (c); MHD_stop_daemon (d); return 2048; } if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock)) { curl_multi_remove_handle (multi, c); curl_multi_cleanup (multi); curl_easy_cleanup (c); MHD_stop_daemon (d); return 4096; } if (MHD_NO == MHD_get_timeout (d, &timeout)) timeout = 100; /* 100ms == INFTY -- CURL bug... */ if ((CURLM_OK == curl_multi_timeout (multi, &ctimeout)) && (ctimeout < (long long)timeout) && (ctimeout >= 0)) timeout = ctimeout; if ( (c == NULL) || (running == 0) ) timeout = 0; /* terminate quickly... */ tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout % 1000) * 1000; if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv)) { if (EINTR == errno) continue; fprintf (stderr, "select failed: %s\n", strerror (errno)); break; } while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform (multi, &running)); if (running == 0) { msg = curl_multi_info_read (multi, &running); if (msg == NULL) break; if (msg->msg == CURLMSG_DONE) { if (msg->data.result != CURLE_OK) printf ("%s failed at %s:%d: `%s'\n", "curl_multi_perform", __FILE__, __LINE__, curl_easy_strerror (msg->data.result)); curl_multi_remove_handle (multi, c); curl_easy_cleanup (c); c = NULL; } } MHD_run (d); } if (c != NULL) { curl_multi_remove_handle (multi, c); curl_easy_cleanup (c); } if ((buf[0] != 'O') || (buf[1] != 'K')) { curl_multi_cleanup (multi); MHD_stop_daemon (d); return 8192; } } curl_multi_cleanup (multi); MHD_stop_daemon (d); if (LOOPCOUNT >= 99) fprintf (stderr, "\n"); return 0; }
/** * Call with the port number as the only argument. * Never terminates (other than by signals, such as CTRL-C). */ int main (int argc, char *const *argv) { #ifdef TEST unsigned char buf[65]; int GetBufferName(unsigned char *buf); int j; for ( j=0; j<20; ++j ) { GetBufferName(buf); int i; for ( i=0; i<20; ++i ) fprintf(stdout, " %d", buf[i]); fprintf(stdout, "\n"); #else struct MHD_Daemon *d; struct timeval tv; struct timeval *tvp; fd_set rs; fd_set ws; fd_set es; MHD_socket max; MHD_UNSIGNED_LONG_LONG mhd_timeout; int Port; if (argc != 2) // No port supplied by command line: default it to 80 Port = 80; else Port = atoi (argv[1]); //MySQLInit(); if ( hid_init() ) return 1; CommandInit(); // Emulate a Recognize command here CmdRecognize(); /* initialize PRNG */ srand ((unsigned int) time (NULL)); d = MHD_start_daemon (MHD_USE_DEBUG, Port, NULL, NULL, &create_response, NULL, MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 15, MHD_OPTION_NOTIFY_COMPLETED, &request_completed_callback, NULL, MHD_OPTION_END); if (NULL == d) return 1; printf("HIDWebServer is listening on port %d\n", Port); while (1) { expire_sessions (); max = 0; FD_ZERO (&rs); FD_ZERO (&ws); FD_ZERO (&es); if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max)) break; /* fatal internal error */ if (MHD_get_timeout (d, &mhd_timeout) == MHD_YES) { tv.tv_sec = mhd_timeout / 1000; tv.tv_usec = (mhd_timeout - (tv.tv_sec * 1000)) * 1000; tvp = &tv; } else tvp = NULL; select (max + 1, &rs, &ws, &es, tvp); MHD_run (d); } MHD_stop_daemon (d); CommandQuit(); hid_exit(); return 0; #endif }