aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-03-04 09:10:03 +0000
committerChristian Grothoff <christian@grothoff.org>2011-03-04 09:10:03 +0000
commit45a0a30893f77a38a8add8a64c3650387840a335 (patch)
tree407c9fb42e6440076b8818f29ad1590220f036b3
parent073951d682f93de20790cda82ef674718fcb9596 (diff)
downloadlibmicrohttpd-45a0a30893f77a38a8add8a64c3650387840a335.tar.gz
libmicrohttpd-45a0a30893f77a38a8add8a64c3650387840a335.zip
also eliminating use of pipe, thereby addressing #1662
-rw-r--r--ChangeLog4
-rw-r--r--src/daemon/connection.c1
-rw-r--r--src/daemon/daemon.c171
-rw-r--r--src/daemon/internal.h5
-rw-r--r--src/examples/minimal_example.c6
5 files changed, 79 insertions, 108 deletions
diff --git a/ChangeLog b/ChangeLog
index 75185723..fa0da138 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
1Fri Mar 4 10:07:18 CET 2011
2 Avoid using a pipe for signalling as well, just use server
3 socket shutdown (also for thread-per-connection). -CG
4
1Thu Mar 3 21:42:47 CET 2011 5Thu Mar 3 21:42:47 CET 2011
2 Fixing issue where Base64 decode fails when char is defined 6 Fixing issue where Base64 decode fails when char is defined
3 as unsigned char (Mantis 1666). -CG/tmayer 7 as unsigned char (Mantis 1666). -CG/tmayer
diff --git a/src/daemon/connection.c b/src/daemon/connection.c
index 49fa6ffe..c7e42af6 100644
--- a/src/daemon/connection.c
+++ b/src/daemon/connection.c
@@ -771,6 +771,7 @@ MHD_connection_get_fdset (struct MHD_Connection *connection,
771 return ret; 771 return ret;
772} 772}
773 773
774
774/** 775/**
775 * Obtain the pollfd for this connection 776 * Obtain the pollfd for this connection
776 * 777 *
diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c
index 460e057e..f12f8207 100644
--- a/src/daemon/daemon.c
+++ b/src/daemon/daemon.c
@@ -547,6 +547,7 @@ MHD_get_fdset (struct MHD_Daemon *daemon,
547 return MHD_YES; 547 return MHD_YES;
548} 548}
549 549
550
550/** 551/**
551 * Main function of the thread that handles an individual 552 * Main function of the thread that handles an individual
552 * connection when MHD_USE_THREAD_PER_CONNECTION is set. 553 * connection when MHD_USE_THREAD_PER_CONNECTION is set.
@@ -563,6 +564,7 @@ MHD_handle_connection (void *data)
563 fd_set ws; 564 fd_set ws;
564 fd_set es; 565 fd_set es;
565 int max; 566 int max;
567 int fd;
566 struct timeval tv; 568 struct timeval tv;
567 struct timeval *tvp; 569 struct timeval *tvp;
568 unsigned int timeout; 570 unsigned int timeout;
@@ -602,24 +604,27 @@ MHD_handle_connection (void *data)
602 FD_ZERO (&rs); 604 FD_ZERO (&rs);
603 FD_ZERO (&ws); 605 FD_ZERO (&ws);
604 FD_ZERO (&es); 606 FD_ZERO (&es);
605 if (-1 != con->daemon->wpipe[0]) 607 if (-1 != (fd = con->daemon->socket_fd))
606 { 608 {
607 max = con->daemon->wpipe[0]; 609 /* we add the listen socket to our read set so
608 FD_SET (con->daemon->wpipe[0], &rs); 610 that if the server is shutdown, we notice it */
611 max = fd;
612 FD_SET (fd, &rs);
609 } 613 }
610 else 614 else
611 max = 0; 615 max = 0;
612 MHD_connection_get_fdset (con, &rs, &ws, &es, &max); 616 MHD_connection_get_fdset (con, &rs, &ws, &es, &max);
613 num_ready = SELECT (max + 1, &rs, &ws, &es, tvp); 617 num_ready = SELECT (max + 1, &rs, &ws, &es, tvp);
614 if (num_ready < 0) { 618 if (num_ready < 0)
615 if (errno == EINTR) 619 {
616 continue; 620 if (errno == EINTR)
621 continue;
617#if HAVE_MESSAGES 622#if HAVE_MESSAGES
618 MHD_DLOG (con->daemon, "Error during select (%d): `%s'\n", max, 623 MHD_DLOG (con->daemon, "Error during select (%d): `%s'\n", max,
619 STRERROR (errno)); 624 STRERROR (errno));
620#endif 625#endif
621 break; 626 break;
622 } 627 }
623 /* call appropriate connection handler if necessary */ 628 /* call appropriate connection handler if necessary */
624 if ((con->socket_fd != -1) && (FD_ISSET (con->socket_fd, &rs))) 629 if ((con->socket_fd != -1) && (FD_ISSET (con->socket_fd, &rs)))
625 con->read_handler (con); 630 con->read_handler (con);
@@ -640,10 +645,20 @@ MHD_handle_connection (void *data)
640 p[0].events |= POLLIN; 645 p[0].events |= POLLIN;
641 if (mp.events & MHD_POLL_ACTION_OUT) 646 if (mp.events & MHD_POLL_ACTION_OUT)
642 p[0].events |= POLLOUT; 647 p[0].events |= POLLOUT;
643 p[1].fd = con->daemon->wpipe[0]; 648 /* we add the listen socket to our read set so
644 p[1].events |= POLLIN; 649 that if the server is shutdown, we notice it */
650
651 fd = con->daemon->socket_fd;
652 p[1].fd = fd;
653 p[1].events |= POLLIN | POLLRDHUP;
645 654
646 if (poll (p, 2, (tvp == NULL) ? -1 : (tv.tv_sec * 1000)) < 0) 655 if (poll (p,
656 (fd != -1) ? 2 : 1,
657 (tvp == NULL)
658 ? -1
659 : ((fd != -1)
660 ? (tv.tv_sec * 1000)
661 : 0)) < 0)
647 { 662 {
648 if (errno == EINTR) 663 if (errno == EINTR)
649 continue; 664 continue;
@@ -689,7 +704,9 @@ MHD_handle_connection (void *data)
689 * @return number of bytes actually received 704 * @return number of bytes actually received
690 */ 705 */
691static ssize_t 706static ssize_t
692recv_param_adapter (struct MHD_Connection *connection, void *other, size_t i) 707recv_param_adapter (struct MHD_Connection *connection,
708 void *other,
709 size_t i)
693{ 710{
694 if (connection->socket_fd == -1) 711 if (connection->socket_fd == -1)
695 return -1; 712 return -1;
@@ -708,7 +725,8 @@ recv_param_adapter (struct MHD_Connection *connection, void *other, size_t i)
708 */ 725 */
709static ssize_t 726static ssize_t
710send_param_adapter (struct MHD_Connection *connection, 727send_param_adapter (struct MHD_Connection *connection,
711 const void *other, size_t i) 728 const void *other,
729 size_t i)
712{ 730{
713#if LINUX 731#if LINUX
714 int fd; 732 int fd;
@@ -841,7 +859,6 @@ create_thread (pthread_t * thread,
841} 859}
842 860
843 861
844
845/** 862/**
846 * Accept an incoming connection and create the MHD_Connection object for 863 * Accept an incoming connection and create the MHD_Connection object for
847 * it. This function also enforces policy by way of checking with the 864 * it. This function also enforces policy by way of checking with the
@@ -1136,7 +1153,8 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon)
1136 * necessiate the use of a timeout right now). 1153 * necessiate the use of a timeout right now).
1137 */ 1154 */
1138int 1155int
1139MHD_get_timeout (struct MHD_Daemon *daemon, unsigned MHD_LONG_LONG *timeout) 1156MHD_get_timeout (struct MHD_Daemon *daemon,
1157 unsigned MHD_LONG_LONG *timeout)
1140{ 1158{
1141 time_t earliest_deadline; 1159 time_t earliest_deadline;
1142 time_t now; 1160 time_t now;
@@ -1179,7 +1197,8 @@ MHD_get_timeout (struct MHD_Daemon *daemon, unsigned MHD_LONG_LONG *timeout)
1179 * @return MHD_NO on serious errors, MHD_YES on success 1197 * @return MHD_NO on serious errors, MHD_YES on success
1180 */ 1198 */
1181static int 1199static int
1182MHD_select (struct MHD_Daemon *daemon, int may_block) 1200MHD_select (struct MHD_Daemon *daemon,
1201 int may_block)
1183{ 1202{
1184 struct MHD_Connection *pos; 1203 struct MHD_Connection *pos;
1185 int num_ready; 1204 int num_ready;
@@ -1199,13 +1218,7 @@ MHD_select (struct MHD_Daemon *daemon, int may_block)
1199 FD_ZERO (&rs); 1218 FD_ZERO (&rs);
1200 FD_ZERO (&ws); 1219 FD_ZERO (&ws);
1201 FD_ZERO (&es); 1220 FD_ZERO (&es);
1202 if (-1 != daemon->wpipe[0]) 1221 max = 0;
1203 {
1204 max = daemon->wpipe[0];
1205 FD_SET (daemon->wpipe[0], &rs);
1206 }
1207 else
1208 max = 0;
1209 if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) 1222 if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
1210 { 1223 {
1211 /* single-threaded, go over everything */ 1224 /* single-threaded, go over everything */
@@ -1307,18 +1320,16 @@ MHD_poll (struct MHD_Daemon *daemon,
1307 pos = pos->next; 1320 pos = pos->next;
1308 } 1321 }
1309 { 1322 {
1310 struct pollfd p[2 + num_connections]; 1323 struct pollfd p[1 + num_connections];
1311 struct MHD_Pollfd mp; 1324 struct MHD_Pollfd mp;
1312 unsigned MHD_LONG_LONG ltimeout; 1325 unsigned MHD_LONG_LONG ltimeout;
1313 unsigned int i; 1326 unsigned int i;
1314 int timeout; 1327 int timeout;
1315 1328
1329 memset (p, 0, sizeof (p));
1316 p[0].fd = daemon->socket_fd; 1330 p[0].fd = daemon->socket_fd;
1317 p[0].events = POLLIN; 1331 p[0].events = POLLIN | POLLRDHUP;
1318 p[0].revents = 0; 1332 p[0].revents = 0;
1319 p[1].fd = daemon->wpipe[0];
1320 p[1].events = POLLIN;
1321 p[1].revents = 0;
1322 if (may_block == MHD_NO) 1333 if (may_block == MHD_NO)
1323 timeout = 0; 1334 timeout = 0;
1324 else if (MHD_YES != MHD_get_timeout (daemon, &ltimeout)) 1335 else if (MHD_YES != MHD_get_timeout (daemon, &ltimeout))
@@ -1332,16 +1343,15 @@ MHD_poll (struct MHD_Daemon *daemon,
1332 { 1343 {
1333 memset(&mp, 0, sizeof (struct MHD_Pollfd)); 1344 memset(&mp, 0, sizeof (struct MHD_Pollfd));
1334 MHD_connection_get_pollfd (pos, &mp); 1345 MHD_connection_get_pollfd (pos, &mp);
1335 memset(&p, 0, sizeof (p)); 1346 p[1+i].fd = mp.fd;
1336 p[2+i].fd = mp.fd;
1337 if (mp.events & MHD_POLL_ACTION_IN) 1347 if (mp.events & MHD_POLL_ACTION_IN)
1338 p[2+i].events |= POLLIN; 1348 p[1+i].events |= POLLIN;
1339 if (mp.events & MHD_POLL_ACTION_OUT) 1349 if (mp.events & MHD_POLL_ACTION_OUT)
1340 p[2+i].events |= POLLOUT; 1350 p[1+i].events |= POLLOUT;
1341 i++; 1351 i++;
1342 pos = pos->next; 1352 pos = pos->next;
1343 } 1353 }
1344 if (poll (p, 2 + num_connections, timeout) < 0) { 1354 if (poll (p, 1 + num_connections, timeout) < 0) {
1345 if (errno == EINTR) 1355 if (errno == EINTR)
1346 return MHD_YES; 1356 return MHD_YES;
1347#if HAVE_MESSAGES 1357#if HAVE_MESSAGES
@@ -1354,21 +1364,29 @@ MHD_poll (struct MHD_Daemon *daemon,
1354 return MHD_NO; 1364 return MHD_NO;
1355 if (daemon->socket_fd < 0) 1365 if (daemon->socket_fd < 0)
1356 return MHD_YES; 1366 return MHD_YES;
1357 if (0 != (p[0].revents & POLLIN))
1358 MHD_accept_connection (daemon);
1359 i = 0; 1367 i = 0;
1360 pos = daemon->connections; 1368 pos = daemon->connections;
1361 while (pos != NULL) 1369 while (pos != NULL)
1362 { 1370 {
1363 if (0 != (p[2+i].revents & POLLIN)) 1371 /* first, sanity checks */
1372 if (i >= num_connections)
1373 break; /* connection list changed somehow, retry later ... */
1374 MHD_connection_get_pollfd (pos, &mp);
1375 if (p[1+i].fd != mp.fd)
1376 break; /* fd mismatch, something else happened, retry later ... */
1377
1378 /* normal handling */
1379 if (0 != (p[1+i].revents & POLLIN))
1364 pos->read_handler (pos); 1380 pos->read_handler (pos);
1365 if (0 != (p[2+i].revents & POLLOUT)) 1381 if (0 != (p[1+i].revents & POLLOUT))
1366 pos->write_handler (pos); 1382 pos->write_handler (pos);
1367 if (pos->socket_fd != -1) 1383 if (pos->socket_fd != -1)
1368 pos->idle_handler (pos); 1384 pos->idle_handler (pos);
1369 i++; 1385 i++;
1370 pos = pos->next; 1386 pos = pos->next;
1371 } 1387 }
1388 if (0 != (p[0].revents & POLLIN))
1389 MHD_accept_connection (daemon);
1372 } 1390 }
1373 return MHD_YES; 1391 return MHD_YES;
1374#else 1392#else
@@ -1797,37 +1815,6 @@ MHD_start_daemon_va (unsigned int options,
1797 retVal->pool_size = MHD_POOL_SIZE_DEFAULT; 1815 retVal->pool_size = MHD_POOL_SIZE_DEFAULT;
1798 retVal->unescape_callback = &MHD_http_unescape; 1816 retVal->unescape_callback = &MHD_http_unescape;
1799 retVal->connection_timeout = 0; /* no timeout */ 1817 retVal->connection_timeout = 0; /* no timeout */
1800 retVal->wpipe[0] = -1;
1801 retVal->wpipe[1] = -1;
1802 if ( (0 != (options & MHD_USE_THREAD_PER_CONNECTION)) ||
1803 (0 != (options & MHD_USE_SELECT_INTERNALLY)) )
1804 {
1805 if (0 != pipe (retVal->wpipe))
1806 {
1807#if HAVE_MESSAGES
1808 FPRINTF(stderr,
1809 "Failed to create control pipe: %s\n",
1810 STRERROR (errno));
1811#endif
1812 free (retVal);
1813 return NULL;
1814 }
1815#ifndef WINDOWS
1816 if ( (0 == (options & MHD_USE_POLL)) &&
1817 (retVal->wpipe[0] >= FD_SETSIZE) )
1818 {
1819#if HAVE_MESSAGES
1820 FPRINTF(stderr,
1821 "file descriptor for control pipe exceeds maximum value\n");
1822#endif
1823 close (retVal->wpipe[0]);
1824 close (retVal->wpipe[1]);
1825 free (retVal);
1826 return NULL;
1827 }
1828#endif
1829 }
1830
1831#ifdef DAUTH_SUPPORT 1818#ifdef DAUTH_SUPPORT
1832 retVal->digest_auth_rand_size = 0; 1819 retVal->digest_auth_rand_size = 0;
1833 retVal->digest_auth_random = NULL; 1820 retVal->digest_auth_random = NULL;
@@ -2217,6 +2204,7 @@ thread_failed:
2217 return NULL; 2204 return NULL;
2218} 2205}
2219 2206
2207
2220/** 2208/**
2221 * Close all connections for the daemon 2209 * Close all connections for the daemon
2222 */ 2210 */
@@ -2239,6 +2227,7 @@ MHD_close_connections (struct MHD_Daemon *daemon)
2239 } 2227 }
2240} 2228}
2241 2229
2230
2242/** 2231/**
2243 * Shutdown an http daemon 2232 * Shutdown an http daemon
2244 */ 2233 */
@@ -2249,15 +2238,12 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
2249 int fd; 2238 int fd;
2250 unsigned int i; 2239 unsigned int i;
2251 int rc; 2240 int rc;
2252 char c;
2253 2241
2254 if (daemon == NULL) 2242 if (daemon == NULL)
2255 return; 2243 return;
2256 daemon->shutdown = MHD_YES; 2244 daemon->shutdown = MHD_YES;
2257 fd = daemon->socket_fd; 2245 fd = daemon->socket_fd;
2258 daemon->socket_fd = -1; 2246 daemon->socket_fd = -1;
2259 if (daemon->wpipe[1] != -1)
2260 write (daemon->wpipe[1], "e", 1);
2261 2247
2262 /* Prepare workers for shutdown */ 2248 /* Prepare workers for shutdown */
2263 for (i = 0; i < daemon->worker_pool_size; ++i) 2249 for (i = 0; i < daemon->worker_pool_size; ++i)
@@ -2265,20 +2251,13 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
2265 daemon->worker_pool[i].shutdown = MHD_YES; 2251 daemon->worker_pool[i].shutdown = MHD_YES;
2266 daemon->worker_pool[i].socket_fd = -1; 2252 daemon->worker_pool[i].socket_fd = -1;
2267 } 2253 }
2268
2269#if OSX
2270 /* without this, either (thread pool = 0) threads would get stuck or
2271 * CLOSE would get stuck if attempted before (thread pool > 0)
2272 * threads have ended */
2273 SHUTDOWN (fd, SHUT_RDWR); 2254 SHUTDOWN (fd, SHUT_RDWR);
2274#else
2275#if DEBUG_CLOSE 2255#if DEBUG_CLOSE
2276#if HAVE_MESSAGES 2256#if HAVE_MESSAGES
2277 MHD_DLOG (daemon, "MHD shutdown, closing listen socket\n"); 2257 MHD_DLOG (daemon, "MHD listen socket shutdown\n");
2278#endif 2258#endif
2279#endif 2259#endif
2280 CLOSE (fd); 2260
2281#endif
2282 2261
2283 /* Signal workers to stop and clean them up */ 2262 /* Signal workers to stop and clean them up */
2284 for (i = 0; i < daemon->worker_pool_size; ++i) 2263 for (i = 0; i < daemon->worker_pool_size; ++i)
@@ -2309,15 +2288,7 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
2309 } 2288 }
2310 } 2289 }
2311 MHD_close_connections (daemon); 2290 MHD_close_connections (daemon);
2312
2313#if OSX
2314#if DEBUG_CLOSE
2315#if HAVE_MESSAGES
2316 MHD_DLOG (daemon, "MHD shutdown, closing listen socket\n");
2317#endif
2318#endif
2319 CLOSE (fd); 2291 CLOSE (fd);
2320#endif
2321 2292
2322 /* TLS clean up */ 2293 /* TLS clean up */
2323#if HTTPS_SUPPORT 2294#if HTTPS_SUPPORT
@@ -2350,17 +2321,10 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
2350#endif 2321#endif
2351 pthread_mutex_destroy (&daemon->per_ip_connection_mutex); 2322 pthread_mutex_destroy (&daemon->per_ip_connection_mutex);
2352 2323
2353 if (daemon->wpipe[1] != -1)
2354 {
2355 /* just to be sure, remove the one char we
2356 wrote into the pipe */
2357 (void) read (daemon->wpipe[0], &c, 1);
2358 close (daemon->wpipe[0]);
2359 close (daemon->wpipe[1]);
2360 }
2361 free (daemon); 2324 free (daemon);
2362} 2325}
2363 2326
2327
2364/** 2328/**
2365 * Obtain information about the given daemon 2329 * Obtain information about the given daemon
2366 * (not fully implemented!). 2330 * (not fully implemented!).
@@ -2384,6 +2348,7 @@ MHD_get_daemon_info (struct MHD_Daemon *daemon,
2384 }; 2348 };
2385} 2349}
2386 2350
2351
2387/** 2352/**
2388 * Sets the global error handler to a different implementation. "cb" 2353 * Sets the global error handler to a different implementation. "cb"
2389 * will only be called in the case of typically fatal, serious 2354 * will only be called in the case of typically fatal, serious
@@ -2405,6 +2370,7 @@ void MHD_set_panic_func (MHD_PanicCallback cb, void *cls)
2405 mhd_panic_cls = cls; 2370 mhd_panic_cls = cls;
2406} 2371}
2407 2372
2373
2408/** 2374/**
2409 * Obtain the version of this library 2375 * Obtain the version of this library
2410 * 2376 *
@@ -2416,6 +2382,7 @@ MHD_get_version (void)
2416 return PACKAGE_VERSION; 2382 return PACKAGE_VERSION;
2417} 2383}
2418 2384
2385
2419#ifdef __GNUC__ 2386#ifdef __GNUC__
2420#define ATTRIBUTE_CONSTRUCTOR __attribute__ ((constructor)) 2387#define ATTRIBUTE_CONSTRUCTOR __attribute__ ((constructor))
2421#define ATTRIBUTE_DESTRUCTOR __attribute__ ((destructor)) 2388#define ATTRIBUTE_DESTRUCTOR __attribute__ ((destructor))
@@ -2428,10 +2395,12 @@ MHD_get_version (void)
2428GCRY_THREAD_OPTION_PTHREAD_IMPL; 2395GCRY_THREAD_OPTION_PTHREAD_IMPL;
2429#endif 2396#endif
2430 2397
2398
2431/** 2399/**
2432 * Initialize do setup work. 2400 * Initialize do setup work.
2433 */ 2401 */
2434void ATTRIBUTE_CONSTRUCTOR MHD_init () 2402void ATTRIBUTE_CONSTRUCTOR
2403MHD_init ()
2435{ 2404{
2436 mhd_panic = &mhd_panic_std; 2405 mhd_panic = &mhd_panic_std;
2437 mhd_panic_cls = NULL; 2406 mhd_panic_cls = NULL;
@@ -2447,7 +2416,9 @@ void ATTRIBUTE_CONSTRUCTOR MHD_init ()
2447#endif 2416#endif
2448} 2417}
2449 2418
2450void ATTRIBUTE_DESTRUCTOR MHD_fini () 2419
2420void ATTRIBUTE_DESTRUCTOR
2421MHD_fini ()
2451{ 2422{
2452#if HTTPS_SUPPORT 2423#if HTTPS_SUPPORT
2453 gnutls_global_deinit (); 2424 gnutls_global_deinit ();
diff --git a/src/daemon/internal.h b/src/daemon/internal.h
index ee499cef..9a3eb8cb 100644
--- a/src/daemon/internal.h
+++ b/src/daemon/internal.h
@@ -857,11 +857,6 @@ struct MHD_Daemon
857 int socket_fd; 857 int socket_fd;
858 858
859 /** 859 /**
860 * Pipe we use to signal shutdown.
861 */
862 int wpipe[2];
863
864 /**
865 * Are we shutting down? 860 * Are we shutting down?
866 */ 861 */
867 int shutdown; 862 int shutdown;
diff --git a/src/examples/minimal_example.c b/src/examples/minimal_example.c
index 8c7d17d9..5bf63444 100644
--- a/src/examples/minimal_example.c
+++ b/src/examples/minimal_example.c
@@ -67,13 +67,13 @@ main (int argc, char *const *argv)
67 printf ("%s PORT\n", argv[0]); 67 printf ("%s PORT\n", argv[0]);
68 return 1; 68 return 1;
69 } 69 }
70 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG | MHD_USE_POLL, 70 d = MHD_start_daemon (// MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG | MHD_USE_POLL,
71 // MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG, 71 MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
72 // MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG | MHD_USE_POLL, 72 // MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG | MHD_USE_POLL,
73 // MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG, 73 // MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG,
74 atoi (argv[1]), 74 atoi (argv[1]),
75 NULL, NULL, &ahc_echo, PAGE, 75 NULL, NULL, &ahc_echo, PAGE,
76 MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 5, 76 MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
77 MHD_OPTION_END); 77 MHD_OPTION_END);
78 if (d == NULL) 78 if (d == NULL)
79 return 1; 79 return 1;