aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd/daemon.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/microhttpd/daemon.c')
-rw-r--r--src/microhttpd/daemon.c310
1 files changed, 156 insertions, 154 deletions
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index d3595fe0..bf01ba9b 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -721,8 +721,8 @@ int
721MHD_get_fdset (struct MHD_Daemon *daemon, 721MHD_get_fdset (struct MHD_Daemon *daemon,
722 fd_set *read_fd_set, 722 fd_set *read_fd_set,
723 fd_set *write_fd_set, 723 fd_set *write_fd_set,
724 fd_set *except_fd_set, 724 fd_set *except_fd_set,
725 MHD_socket *max_fd) 725 MHD_socket *max_fd)
726{ 726{
727 return MHD_get_fdset2 (daemon, 727 return MHD_get_fdset2 (daemon,
728 read_fd_set, 728 read_fd_set,
@@ -2344,11 +2344,11 @@ psk_gnutls_adapter (gnutls_session_t session,
2344 */ 2344 */
2345static int 2345static int
2346internal_add_connection (struct MHD_Daemon *daemon, 2346internal_add_connection (struct MHD_Daemon *daemon,
2347 MHD_socket client_socket, 2347 MHD_socket client_socket,
2348 const struct sockaddr *addr, 2348 const struct sockaddr *addr,
2349 socklen_t addrlen, 2349 socklen_t addrlen,
2350 bool external_add, 2350 bool external_add,
2351 bool non_blck) 2351 bool non_blck)
2352{ 2352{
2353 struct MHD_Connection *connection; 2353 struct MHD_Connection *connection;
2354#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2354#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
@@ -2362,8 +2362,8 @@ internal_add_connection (struct MHD_Daemon *daemon,
2362 if ((external_add) && (NULL != daemon->worker_pool)) 2362 if ((external_add) && (NULL != daemon->worker_pool))
2363 { 2363 {
2364 /* have a pool, try to find a pool with capacity; we use the 2364 /* have a pool, try to find a pool with capacity; we use the
2365 socket as the initial offset into the pool for load 2365 socket as the initial offset into the pool for load
2366 balancing */ 2366 balancing */
2367 for (i = 0; i < daemon->worker_pool_size; ++i) 2367 for (i = 0; i < daemon->worker_pool_size; ++i)
2368 { 2368 {
2369 struct MHD_Daemon * const worker = 2369 struct MHD_Daemon * const worker =
@@ -2448,7 +2448,7 @@ internal_add_connection (struct MHD_Daemon *daemon,
2448 /* apply connection acceptance policy if present */ 2448 /* apply connection acceptance policy if present */
2449 if ( (NULL != daemon->apc) && 2449 if ( (NULL != daemon->apc) &&
2450 (MHD_NO == daemon->apc (daemon->apc_cls, 2450 (MHD_NO == daemon->apc (daemon->apc_cls,
2451 addr, 2451 addr,
2452 addrlen)) ) 2452 addrlen)) )
2453 { 2453 {
2454#if DEBUG_CLOSE 2454#if DEBUG_CLOSE
@@ -2472,8 +2472,8 @@ internal_add_connection (struct MHD_Daemon *daemon,
2472 eno = errno; 2472 eno = errno;
2473#ifdef HAVE_MESSAGES 2473#ifdef HAVE_MESSAGES
2474 MHD_DLOG (daemon, 2474 MHD_DLOG (daemon,
2475 "Error allocating memory: %s\n", 2475 "Error allocating memory: %s\n",
2476 MHD_strerror_ (errno)); 2476 MHD_strerror_ (errno));
2477#endif 2477#endif
2478 MHD_socket_close_chk_ (client_socket); 2478 MHD_socket_close_chk_ (client_socket);
2479 MHD_ip_limit_del (daemon, 2479 MHD_ip_limit_del (daemon,
@@ -2487,8 +2487,8 @@ internal_add_connection (struct MHD_Daemon *daemon,
2487 { 2487 {
2488#ifdef HAVE_MESSAGES 2488#ifdef HAVE_MESSAGES
2489 MHD_DLOG (daemon, 2489 MHD_DLOG (daemon,
2490 _("Error allocating memory: %s\n"), 2490 _("Error allocating memory: %s\n"),
2491 MHD_strerror_ (errno)); 2491 MHD_strerror_ (errno));
2492#endif 2492#endif
2493 MHD_socket_close_chk_ (client_socket); 2493 MHD_socket_close_chk_ (client_socket);
2494 MHD_ip_limit_del (daemon, 2494 MHD_ip_limit_del (daemon,
@@ -2507,8 +2507,8 @@ internal_add_connection (struct MHD_Daemon *daemon,
2507 eno = errno; 2507 eno = errno;
2508#ifdef HAVE_MESSAGES 2508#ifdef HAVE_MESSAGES
2509 MHD_DLOG (daemon, 2509 MHD_DLOG (daemon,
2510 _("Error allocating memory: %s\n"), 2510 _("Error allocating memory: %s\n"),
2511 MHD_strerror_ (errno)); 2511 MHD_strerror_ (errno));
2512#endif 2512#endif
2513 MHD_socket_close_chk_ (client_socket); 2513 MHD_socket_close_chk_ (client_socket);
2514 MHD_ip_limit_del (daemon, 2514 MHD_ip_limit_del (daemon,
@@ -2566,8 +2566,8 @@ internal_add_connection (struct MHD_Daemon *daemon,
2566 /* set needed credentials for certificate authentication. */ 2566 /* set needed credentials for certificate authentication. */
2567 case GNUTLS_CRD_CERTIFICATE: 2567 case GNUTLS_CRD_CERTIFICATE:
2568 gnutls_credentials_set (connection->tls_session, 2568 gnutls_credentials_set (connection->tls_session,
2569 GNUTLS_CRD_CERTIFICATE, 2569 GNUTLS_CRD_CERTIFICATE,
2570 daemon->x509_cred); 2570 daemon->x509_cred);
2571 break; 2571 break;
2572 case GNUTLS_CRD_PSK: 2572 case GNUTLS_CRD_PSK:
2573 gnutls_credentials_set (connection->tls_session, 2573 gnutls_credentials_set (connection->tls_session,
@@ -2596,18 +2596,18 @@ internal_add_connection (struct MHD_Daemon *daemon,
2596 } 2596 }
2597#if (GNUTLS_VERSION_NUMBER+0 >= 0x030109) && !defined(_WIN64) 2597#if (GNUTLS_VERSION_NUMBER+0 >= 0x030109) && !defined(_WIN64)
2598 gnutls_transport_set_int (connection->tls_session, 2598 gnutls_transport_set_int (connection->tls_session,
2599 (int)(client_socket)); 2599 (int)(client_socket));
2600#else /* GnuTLS before 3.1.9 or Win x64 */ 2600#else /* GnuTLS before 3.1.9 or Win x64 */
2601 gnutls_transport_set_ptr (connection->tls_session, 2601 gnutls_transport_set_ptr (connection->tls_session,
2602 (gnutls_transport_ptr_t)(intptr_t)(client_socket)); 2602 (gnutls_transport_ptr_t)(intptr_t)(client_socket));
2603#endif /* GnuTLS before 3.1.9 */ 2603#endif /* GnuTLS before 3.1.9 */
2604#ifdef MHD_TLSLIB_NEED_PUSH_FUNC 2604#ifdef MHD_TLSLIB_NEED_PUSH_FUNC
2605 gnutls_transport_set_push_function (connection->tls_session, 2605 gnutls_transport_set_push_function (connection->tls_session,
2606 MHD_tls_push_func_); 2606 MHD_tls_push_func_);
2607#endif /* MHD_TLSLIB_NEED_PUSH_FUNC */ 2607#endif /* MHD_TLSLIB_NEED_PUSH_FUNC */
2608 if (daemon->https_mem_trust) 2608 if (daemon->https_mem_trust)
2609 gnutls_certificate_server_set_request (connection->tls_session, 2609 gnutls_certificate_server_set_request (connection->tls_session,
2610 GNUTLS_CERT_REQUEST); 2610 GNUTLS_CERT_REQUEST);
2611#else /* ! HTTPS_SUPPORT */ 2611#else /* ! HTTPS_SUPPORT */
2612 eno = EINVAL; 2612 eno = EINVAL;
2613 goto cleanup; 2613 goto cleanup;
@@ -2641,8 +2641,8 @@ internal_add_connection (struct MHD_Daemon *daemon,
2641 connection); 2641 connection);
2642 } 2642 }
2643 DLL_insert (daemon->connections_head, 2643 DLL_insert (daemon->connections_head,
2644 daemon->connections_tail, 2644 daemon->connections_tail,
2645 connection); 2645 connection);
2646#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2646#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2647 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 2647 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
2648#endif 2648#endif
@@ -2661,13 +2661,13 @@ internal_add_connection (struct MHD_Daemon *daemon,
2661 &thread_main_handle_connection, 2661 &thread_main_handle_connection,
2662 connection)) 2662 connection))
2663 { 2663 {
2664 eno = errno; 2664 eno = errno;
2665#ifdef HAVE_MESSAGES 2665#ifdef HAVE_MESSAGES
2666 MHD_DLOG (daemon, 2666 MHD_DLOG (daemon,
2667 "Failed to create a thread: %s\n", 2667 "Failed to create a thread: %s\n",
2668 MHD_strerror_ (eno)); 2668 MHD_strerror_ (eno));
2669#endif 2669#endif
2670 goto cleanup; 2670 goto cleanup;
2671 } 2671 }
2672 } 2672 }
2673 else 2673 else
@@ -2683,9 +2683,9 @@ internal_add_connection (struct MHD_Daemon *daemon,
2683 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET; 2683 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
2684 event.data.ptr = connection; 2684 event.data.ptr = connection;
2685 if (0 != epoll_ctl (daemon->epoll_fd, 2685 if (0 != epoll_ctl (daemon->epoll_fd,
2686 EPOLL_CTL_ADD, 2686 EPOLL_CTL_ADD,
2687 client_socket, 2687 client_socket,
2688 &event)) 2688 &event))
2689 { 2689 {
2690 eno = errno; 2690 eno = errno;
2691#ifdef HAVE_MESSAGES 2691#ifdef HAVE_MESSAGES
@@ -2702,8 +2702,8 @@ internal_add_connection (struct MHD_Daemon *daemon,
2702 connection->epoll_state |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY 2702 connection->epoll_state |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY
2703 | MHD_EPOLL_STATE_IN_EREADY_EDLL; 2703 | MHD_EPOLL_STATE_IN_EREADY_EDLL;
2704 EDLL_insert (daemon->eready_head, 2704 EDLL_insert (daemon->eready_head,
2705 daemon->eready_tail, 2705 daemon->eready_tail,
2706 connection); 2706 connection);
2707 } 2707 }
2708 } 2708 }
2709 else /* This 'else' is combined with next 'if'. */ 2709 else /* This 'else' is combined with next 'if'. */
@@ -3041,12 +3041,12 @@ resume_suspended_connections (struct MHD_Daemon *daemon)
3041 { /* Wake up suspended connections. */ 3041 { /* Wake up suspended connections. */
3042 if (! MHD_itc_activate_(daemon->itc, 3042 if (! MHD_itc_activate_(daemon->itc,
3043 "w")) 3043 "w"))
3044 { 3044 {
3045#ifdef HAVE_MESSAGES 3045#ifdef HAVE_MESSAGES
3046 MHD_DLOG (daemon, 3046 MHD_DLOG (daemon,
3047 _("Failed to signal resume of connection via inter-thread communication channel.")); 3047 _("Failed to signal resume of connection via inter-thread communication channel."));
3048#endif 3048#endif
3049 } 3049 }
3050 } 3050 }
3051 return ret; 3051 return ret;
3052} 3052}
@@ -3081,11 +3081,12 @@ resume_suspended_connections (struct MHD_Daemon *daemon)
3081 */ 3081 */
3082int 3082int
3083MHD_add_connection (struct MHD_Daemon *daemon, 3083MHD_add_connection (struct MHD_Daemon *daemon,
3084 MHD_socket client_socket, 3084 MHD_socket client_socket,
3085 const struct sockaddr *addr, 3085 const struct sockaddr *addr,
3086 socklen_t addrlen) 3086 socklen_t addrlen)
3087{ 3087{
3088 bool sk_nonbl; 3088 bool sk_nonbl;
3089
3089 if (! MHD_socket_nonblocking_ (client_socket)) 3090 if (! MHD_socket_nonblocking_ (client_socket))
3090 { 3091 {
3091#ifdef HAVE_MESSAGES 3092#ifdef HAVE_MESSAGES
@@ -3116,11 +3117,11 @@ MHD_add_connection (struct MHD_Daemon *daemon,
3116#endif 3117#endif
3117 } 3118 }
3118 return internal_add_connection (daemon, 3119 return internal_add_connection (daemon,
3119 client_socket, 3120 client_socket,
3120 addr, 3121 addr,
3121 addrlen, 3122 addrlen,
3122 true, 3123 true,
3123 sk_nonbl); 3124 sk_nonbl);
3124} 3125}
3125 3126
3126 3127
@@ -3253,9 +3254,9 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
3253#endif 3254#endif
3254 (void) internal_add_connection (daemon, 3255 (void) internal_add_connection (daemon,
3255 s, 3256 s,
3256 addr, 3257 addr,
3257 addrlen, 3258 addrlen,
3258 false, 3259 false,
3259 sk_nonbl); 3260 sk_nonbl);
3260 return MHD_YES; 3261 return MHD_YES;
3261} 3262}
@@ -3381,7 +3382,7 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon)
3381 */ 3382 */
3382int 3383int
3383MHD_get_timeout (struct MHD_Daemon *daemon, 3384MHD_get_timeout (struct MHD_Daemon *daemon,
3384 MHD_UNSIGNED_LONG_LONG *timeout) 3385 MHD_UNSIGNED_LONG_LONG *timeout)
3385{ 3386{
3386 time_t earliest_deadline; 3387 time_t earliest_deadline;
3387 time_t now; 3388 time_t now;
@@ -4177,28 +4178,29 @@ run_epoll_for_upgrade (struct MHD_Daemon *daemon)
4177 struct MHD_UpgradeResponseHandle * prev; 4178 struct MHD_UpgradeResponseHandle * prev;
4178 4179
4179 num_events = MAX_EVENTS; 4180 num_events = MAX_EVENTS;
4180 while (MAX_EVENTS == num_events) 4181 while (0 != num_events)
4181 { 4182 {
4182 unsigned int i; 4183 unsigned int i;
4183 /* update event masks */ 4184 /* update event masks */
4184 num_events = epoll_wait (daemon->epoll_upgrade_fd, 4185 num_events = epoll_wait (daemon->epoll_upgrade_fd,
4185 events, 4186 events,
4186 MAX_EVENTS, 4187 MAX_EVENTS,
4187 0); 4188 0);
4188 if (-1 == num_events) 4189 if (-1 == num_events)
4189 { 4190 {
4190 const int err = MHD_socket_get_error_ (); 4191 const int err = MHD_socket_get_error_ ();
4192
4191 if (MHD_SCKT_ERR_IS_EINTR_ (err)) 4193 if (MHD_SCKT_ERR_IS_EINTR_ (err))
4192 return MHD_YES; 4194 return MHD_YES;
4193#ifdef HAVE_MESSAGES 4195#ifdef HAVE_MESSAGES
4194 MHD_DLOG (daemon, 4196 MHD_DLOG (daemon,
4195 _("Call to epoll_wait failed: %s\n"), 4197 _("Call to epoll_wait failed: %s\n"),
4196 MHD_socket_strerr_ (err)); 4198 MHD_socket_strerr_ (err));
4197#endif 4199#endif
4198 return MHD_NO; 4200 return MHD_NO;
4199 } 4201 }
4200 for (i = 0; i < (unsigned int) num_events; i++) 4202 for (i = 0; i < (unsigned int) num_events; i++)
4201 { 4203 {
4202 struct UpgradeEpollHandle * const ueh = events[i].data.ptr; 4204 struct UpgradeEpollHandle * const ueh = events[i].data.ptr;
4203 struct MHD_UpgradeResponseHandle * const urh = ueh->urh; 4205 struct MHD_UpgradeResponseHandle * const urh = ueh->urh;
4204 bool new_err_state = false; 4206 bool new_err_state = false;
@@ -4216,24 +4218,24 @@ run_epoll_for_upgrade (struct MHD_Daemon *daemon)
4216 4218
4217 if ( (0 == (ueh->celi & MHD_EPOLL_STATE_ERROR)) && 4219 if ( (0 == (ueh->celi & MHD_EPOLL_STATE_ERROR)) &&
4218 (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) ) 4220 (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) )
4219 { 4221 {
4220 /* Process new error state only one time 4222 /* Process new error state only one time
4221 * and avoid continuously marking this connection 4223 * and avoid continuously marking this connection
4222 * as 'ready'. */ 4224 * as 'ready'. */
4223 ueh->celi |= MHD_EPOLL_STATE_ERROR; 4225 ueh->celi |= MHD_EPOLL_STATE_ERROR;
4224 new_err_state = true; 4226 new_err_state = true;
4225 } 4227 }
4226 4228
4227 if (! urh->in_eready_list) 4229 if (! urh->in_eready_list)
4228 { 4230 {
4229 if (new_err_state || 4231 if (new_err_state ||
4230 is_urh_ready(urh)) 4232 is_urh_ready(urh))
4231 { 4233 {
4232 EDLL_insert (daemon->eready_urh_head, 4234 EDLL_insert (daemon->eready_urh_head,
4233 daemon->eready_urh_tail, 4235 daemon->eready_urh_tail,
4234 urh); 4236 urh);
4235 urh->in_eready_list = true; 4237 urh->in_eready_list = true;
4236 } 4238 }
4237 } 4239 }
4238 } 4240 }
4239 } 4241 }
@@ -4245,8 +4247,8 @@ run_epoll_for_upgrade (struct MHD_Daemon *daemon)
4245 if (! is_urh_ready(pos)) 4247 if (! is_urh_ready(pos))
4246 { 4248 {
4247 EDLL_remove (daemon->eready_urh_head, 4249 EDLL_remove (daemon->eready_urh_head,
4248 daemon->eready_urh_tail, 4250 daemon->eready_urh_tail,
4249 pos); 4251 pos);
4250 pos->in_eready_list = false; 4252 pos->in_eready_list = false;
4251 } 4253 }
4252 /* Finished forwarding? */ 4254 /* Finished forwarding? */
@@ -4261,7 +4263,7 @@ run_epoll_for_upgrade (struct MHD_Daemon *daemon)
4261 * will be moved immediately to cleanup list. Otherwise 4263 * will be moved immediately to cleanup list. Otherwise
4262 * connection will stay in suspended list until 'pos' will 4264 * connection will stay in suspended list until 'pos' will
4263 * be marked with 'was_closed' by application. */ 4265 * be marked with 'was_closed' by application. */
4264 MHD_resume_connection(pos->connection); 4266 MHD_resume_connection (pos->connection);
4265 } 4267 }
4266 } 4268 }
4267 4269
@@ -4286,7 +4288,7 @@ static const char * const epoll_itc_marker = "itc_marker";
4286 */ 4288 */
4287static int 4289static int
4288MHD_epoll (struct MHD_Daemon *daemon, 4290MHD_epoll (struct MHD_Daemon *daemon,
4289 int may_block) 4291 int may_block)
4290{ 4292{
4291#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4293#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4292 static const char * const upgrade_marker = "upgrade_ptr"; 4294 static const char * const upgrade_marker = "upgrade_ptr";
@@ -4301,7 +4303,7 @@ MHD_epoll (struct MHD_Daemon *daemon,
4301 unsigned int i; 4303 unsigned int i;
4302 MHD_socket ls; 4304 MHD_socket ls;
4303#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4305#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4304 int run_upgraded = MHD_NO; 4306 bool run_upgraded = false;
4305#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 4307#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4306 4308
4307 if (-1 == daemon->epoll_fd) 4309 if (-1 == daemon->epoll_fd)
@@ -4317,50 +4319,50 @@ MHD_epoll (struct MHD_Daemon *daemon,
4317 event.events = EPOLLIN; 4319 event.events = EPOLLIN;
4318 event.data.ptr = daemon; 4320 event.data.ptr = daemon;
4319 if (0 != epoll_ctl (daemon->epoll_fd, 4321 if (0 != epoll_ctl (daemon->epoll_fd,
4320 EPOLL_CTL_ADD, 4322 EPOLL_CTL_ADD,
4321 ls, 4323 ls,
4322 &event)) 4324 &event))
4323 { 4325 {
4324#ifdef HAVE_MESSAGES 4326#ifdef HAVE_MESSAGES
4325 MHD_DLOG (daemon, 4327 MHD_DLOG (daemon,
4326 _("Call to epoll_ctl failed: %s\n"), 4328 _("Call to epoll_ctl failed: %s\n"),
4327 MHD_socket_last_strerr_ ()); 4329 MHD_socket_last_strerr_ ());
4328#endif 4330#endif
4329 return MHD_NO; 4331 return MHD_NO;
4330 } 4332 }
4331 daemon->listen_socket_in_epoll = true; 4333 daemon->listen_socket_in_epoll = true;
4332 } 4334 }
4333 if ( (daemon->was_quiesced) && 4335 if ( (daemon->was_quiesced) &&
4334 (daemon->listen_socket_in_epoll) ) 4336 (daemon->listen_socket_in_epoll) )
4335 { 4337 {
4336 if ( (0 != epoll_ctl (daemon->epoll_fd, 4338 if ( (0 != epoll_ctl (daemon->epoll_fd,
4337 EPOLL_CTL_DEL, 4339 EPOLL_CTL_DEL,
4338 ls, 4340 ls,
4339 NULL)) && 4341 NULL)) &&
4340 (ENOENT != errno) ) /* ENOENT can happen due to race with 4342 (ENOENT != errno) ) /* ENOENT can happen due to race with
4341 #MHD_quiesce_daemon() */ 4343 #MHD_quiesce_daemon() */
4342 MHD_PANIC ("Failed to remove listen FD from epoll set\n"); 4344 MHD_PANIC ("Failed to remove listen FD from epoll set\n");
4343 daemon->listen_socket_in_epoll = false; 4345 daemon->listen_socket_in_epoll = false;
4344 } 4346 }
4345 4347
4346#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4348#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4347 if ( (! daemon->upgrade_fd_in_epoll) && 4349 if ( ( (! daemon->upgrade_fd_in_epoll) &&
4348 (-1 != daemon->epoll_upgrade_fd) ) 4350 (-1 != daemon->epoll_upgrade_fd) ) )
4349 { 4351 {
4350 event.events = EPOLLIN | EPOLLOUT; 4352 event.events = EPOLLIN | EPOLLOUT;
4351 event.data.ptr = (void *) upgrade_marker; 4353 event.data.ptr = (void *) upgrade_marker;
4352 if (0 != epoll_ctl (daemon->epoll_fd, 4354 if (0 != epoll_ctl (daemon->epoll_fd,
4353 EPOLL_CTL_ADD, 4355 EPOLL_CTL_ADD,
4354 daemon->epoll_upgrade_fd, 4356 daemon->epoll_upgrade_fd,
4355 &event)) 4357 &event))
4356 { 4358 {
4357#ifdef HAVE_MESSAGES 4359#ifdef HAVE_MESSAGES
4358 MHD_DLOG (daemon, 4360 MHD_DLOG (daemon,
4359 _("Call to epoll_ctl failed: %s\n"), 4361 _("Call to epoll_ctl failed: %s\n"),
4360 MHD_socket_last_strerr_ ()); 4362 MHD_socket_last_strerr_ ());
4361#endif 4363#endif
4362 return MHD_NO; 4364 return MHD_NO;
4363 } 4365 }
4364 daemon->upgrade_fd_in_epoll = true; 4366 daemon->upgrade_fd_in_epoll = true;
4365 } 4367 }
4366#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 4368#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
@@ -4372,10 +4374,10 @@ MHD_epoll (struct MHD_Daemon *daemon,
4372 /* we're at the connection limit, disable listen socket 4374 /* we're at the connection limit, disable listen socket
4373 for event loop for now */ 4375 for event loop for now */
4374 if (0 != epoll_ctl (daemon->epoll_fd, 4376 if (0 != epoll_ctl (daemon->epoll_fd,
4375 EPOLL_CTL_DEL, 4377 EPOLL_CTL_DEL,
4376 ls, 4378 ls,
4377 NULL)) 4379 NULL))
4378 MHD_PANIC (_("Failed to remove listen FD from epoll set\n")); 4380 MHD_PANIC (_("Failed to remove listen FD from epoll set\n"));
4379 daemon->listen_socket_in_epoll = false; 4381 daemon->listen_socket_in_epoll = false;
4380 } 4382 }
4381 4383
@@ -4386,15 +4388,15 @@ MHD_epoll (struct MHD_Daemon *daemon,
4386 if (MHD_YES == may_block) 4388 if (MHD_YES == may_block)
4387 { 4389 {
4388 if (MHD_YES == MHD_get_timeout (daemon, 4390 if (MHD_YES == MHD_get_timeout (daemon,
4389 &timeout_ll)) 4391 &timeout_ll))
4390 { 4392 {
4391 if (timeout_ll >= (MHD_UNSIGNED_LONG_LONG) INT_MAX) 4393 if (timeout_ll >= (MHD_UNSIGNED_LONG_LONG) INT_MAX)
4392 timeout_ms = INT_MAX; 4394 timeout_ms = INT_MAX;
4393 else 4395 else
4394 timeout_ms = (int) timeout_ll; 4396 timeout_ms = (int) timeout_ll;
4395 } 4397 }
4396 else 4398 else
4397 timeout_ms = -1; 4399 timeout_ms = -1;
4398 } 4400 }
4399 else 4401 else
4400 timeout_ms = 0; 4402 timeout_ms = 0;
@@ -4413,33 +4415,33 @@ MHD_epoll (struct MHD_Daemon *daemon,
4413 { 4415 {
4414 /* update event masks */ 4416 /* update event masks */
4415 num_events = epoll_wait (daemon->epoll_fd, 4417 num_events = epoll_wait (daemon->epoll_fd,
4416 events, 4418 events,
4417 MAX_EVENTS, 4419 MAX_EVENTS,
4418 timeout_ms); 4420 timeout_ms);
4419 if (-1 == num_events) 4421 if (-1 == num_events)
4420 { 4422 {
4421 const int err = MHD_socket_get_error_ (); 4423 const int err = MHD_socket_get_error_ ();
4422 if (MHD_SCKT_ERR_IS_EINTR_ (err)) 4424 if (MHD_SCKT_ERR_IS_EINTR_ (err))
4423 return MHD_YES; 4425 return MHD_YES;
4424#ifdef HAVE_MESSAGES 4426#ifdef HAVE_MESSAGES
4425 MHD_DLOG (daemon, 4427 MHD_DLOG (daemon,
4426 _("Call to epoll_wait failed: %s\n"), 4428 _("Call to epoll_wait failed: %s\n"),
4427 MHD_socket_strerr_ (err)); 4429 MHD_socket_strerr_ (err));
4428#endif 4430#endif
4429 return MHD_NO; 4431 return MHD_NO;
4430 } 4432 }
4431 for (i=0;i<(unsigned int) num_events;i++) 4433 for (i=0;i<(unsigned int) num_events;i++)
4432 { 4434 {
4433 /* First, check for the values of `ptr` that would indicate 4435 /* First, check for the values of `ptr` that would indicate
4434 that this event is not about a normal connection. */ 4436 that this event is not about a normal connection. */
4435 if (NULL == events[i].data.ptr) 4437 if (NULL == events[i].data.ptr)
4436 continue; /* shutdown signal! */ 4438 continue; /* shutdown signal! */
4437#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4439#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4438 if (upgrade_marker == events[i].data.ptr) 4440 if (upgrade_marker == events[i].data.ptr)
4439 { 4441 {
4440 /* activity on an upgraded connection, we process 4442 /* activity on an upgraded connection, we process
4441 those in a separate epoll() */ 4443 those in a separate epoll() */
4442 run_upgraded = MHD_YES; 4444 run_upgraded = true;
4443 continue; 4445 continue;
4444 } 4446 }
4445#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 4447#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
@@ -4450,8 +4452,8 @@ MHD_epoll (struct MHD_Daemon *daemon,
4450 MHD_itc_clear_ (daemon->itc); 4452 MHD_itc_clear_ (daemon->itc);
4451 continue; 4453 continue;
4452 } 4454 }
4453 if (daemon == events[i].data.ptr) 4455 if (daemon == events[i].data.ptr)
4454 { 4456 {
4455 /* Check for error conditions on listen socket. */ 4457 /* Check for error conditions on listen socket. */
4456 /* FIXME: Initiate MHD_quiesce_daemon() to prevent busy waiting? */ 4458 /* FIXME: Initiate MHD_quiesce_daemon() to prevent busy waiting? */
4457 if (0 == (events[i].events & (EPOLLERR | EPOLLHUP))) 4459 if (0 == (events[i].events & (EPOLLERR | EPOLLHUP)))
@@ -4466,9 +4468,9 @@ MHD_epoll (struct MHD_Daemon *daemon,
4466 (daemon->connections < daemon->connection_limit) && 4468 (daemon->connections < daemon->connection_limit) &&
4467 (! daemon->at_limit) ) 4469 (! daemon->at_limit) )
4468 series_length++; 4470 series_length++;
4469 } 4471 }
4470 continue; 4472 continue;
4471 } 4473 }
4472 /* this is an event relating to a 'normal' connection, 4474 /* this is an event relating to a 'normal' connection,
4473 remember the event and if appropriate mark the 4475 remember the event and if appropriate mark the
4474 connection as 'eready'. */ 4476 connection as 'eready'. */
@@ -4517,7 +4519,7 @@ MHD_epoll (struct MHD_Daemon *daemon,
4517 } 4519 }
4518 4520
4519#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4521#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4520 if (MHD_YES == run_upgraded) 4522 if (run_upgraded || (NULL != daemon->eready_urh_head))
4521 run_epoll_for_upgrade (daemon); 4523 run_epoll_for_upgrade (daemon);
4522#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 4524#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4523 4525
@@ -4605,22 +4607,22 @@ MHD_run (struct MHD_Daemon *daemon)
4605 (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) ) 4607 (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) )
4606 return MHD_NO; 4608 return MHD_NO;
4607 if (0 != (daemon->options & MHD_USE_POLL)) 4609 if (0 != (daemon->options & MHD_USE_POLL))
4608 { 4610 {
4609 MHD_poll (daemon, MHD_NO); 4611 MHD_poll (daemon, MHD_NO);
4610 MHD_cleanup_connections (daemon); 4612 MHD_cleanup_connections (daemon);
4611 } 4613 }
4612#ifdef EPOLL_SUPPORT 4614#ifdef EPOLL_SUPPORT
4613 else if (0 != (daemon->options & MHD_USE_EPOLL)) 4615 else if (0 != (daemon->options & MHD_USE_EPOLL))
4614 { 4616 {
4615 MHD_epoll (daemon, MHD_NO); 4617 MHD_epoll (daemon, MHD_NO);
4616 MHD_cleanup_connections (daemon); 4618 MHD_cleanup_connections (daemon);
4617 } 4619 }
4618#endif 4620#endif
4619 else 4621 else
4620 { 4622 {
4621 MHD_select (daemon, MHD_NO); 4623 MHD_select (daemon, MHD_NO);
4622 /* MHD_select does MHD_cleanup_connections already */ 4624 /* MHD_select does MHD_cleanup_connections already */
4623 } 4625 }
4624 return MHD_YES; 4626 return MHD_YES;
4625} 4627}
4626 4628
@@ -4822,26 +4824,26 @@ MHD_quiesce_daemon (struct MHD_Daemon *daemon)
4822 if (NULL != daemon->worker_pool) 4824 if (NULL != daemon->worker_pool)
4823 for (i = 0; i < daemon->worker_pool_size; i++) 4825 for (i = 0; i < daemon->worker_pool_size; i++)
4824 { 4826 {
4825 daemon->worker_pool[i].was_quiesced = true; 4827 daemon->worker_pool[i].was_quiesced = true;
4826#ifdef EPOLL_SUPPORT 4828#ifdef EPOLL_SUPPORT
4827 if ( (0 != (daemon->options & MHD_USE_EPOLL)) && 4829 if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
4828 (-1 != daemon->worker_pool[i].epoll_fd) && 4830 (-1 != daemon->worker_pool[i].epoll_fd) &&
4829 (daemon->worker_pool[i].listen_socket_in_epoll) ) 4831 (daemon->worker_pool[i].listen_socket_in_epoll) )
4830 {
4831 if (0 != epoll_ctl (daemon->worker_pool[i].epoll_fd,
4832 EPOLL_CTL_DEL,
4833 ret,
4834 NULL))
4835 MHD_PANIC (_("Failed to remove listen FD from epoll set\n"));
4836 daemon->worker_pool[i].listen_socket_in_epoll = false;
4837 }
4838 else
4839#endif
4840 if (MHD_ITC_IS_VALID_(daemon->worker_pool[i].itc))
4841 { 4832 {
4842 if (! MHD_itc_activate_ (daemon->worker_pool[i].itc, "q")) 4833 if (0 != epoll_ctl (daemon->worker_pool[i].epoll_fd,
4843 MHD_PANIC (_("Failed to signal quiesce via inter-thread communication channel")); 4834 EPOLL_CTL_DEL,
4835 ret,
4836 NULL))
4837 MHD_PANIC (_("Failed to remove listen FD from epoll set\n"));
4838 daemon->worker_pool[i].listen_socket_in_epoll = false;
4844 } 4839 }
4840 else
4841#endif
4842 if (MHD_ITC_IS_VALID_(daemon->worker_pool[i].itc))
4843 {
4844 if (! MHD_itc_activate_ (daemon->worker_pool[i].itc, "q"))
4845 MHD_PANIC (_("Failed to signal quiesce via inter-thread communication channel"));
4846 }
4845 } 4847 }
4846#endif 4848#endif
4847 daemon->was_quiesced = true; 4849 daemon->was_quiesced = true;
@@ -4856,7 +4858,7 @@ MHD_quiesce_daemon (struct MHD_Daemon *daemon)
4856 NULL)) && 4858 NULL)) &&
4857 (ENOENT != errno) ) /* ENOENT can happen due to race with 4859 (ENOENT != errno) ) /* ENOENT can happen due to race with
4858 #MHD_epoll() */ 4860 #MHD_epoll() */
4859 MHD_PANIC ("Failed to remove listen FD from epoll set\n"); 4861 MHD_PANIC ("Failed to remove listen FD from epoll set\n");
4860 daemon->listen_socket_in_epoll = false; 4862 daemon->listen_socket_in_epoll = false;
4861 } 4863 }
4862#endif 4864#endif
@@ -4890,8 +4892,8 @@ typedef void
4890 */ 4892 */
4891static int 4893static int
4892parse_options_va (struct MHD_Daemon *daemon, 4894parse_options_va (struct MHD_Daemon *daemon,
4893 const struct sockaddr **servaddr, 4895 const struct sockaddr **servaddr,
4894 va_list ap); 4896 va_list ap);
4895 4897
4896 4898
4897/** 4899/**
@@ -4929,8 +4931,8 @@ parse_options (struct MHD_Daemon *daemon,
4929 */ 4931 */
4930static int 4932static int
4931parse_options_va (struct MHD_Daemon *daemon, 4933parse_options_va (struct MHD_Daemon *daemon,
4932 const struct sockaddr **servaddr, 4934 const struct sockaddr **servaddr,
4933 va_list ap) 4935 va_list ap)
4934{ 4936{
4935 enum MHD_OPTION opt; 4937 enum MHD_OPTION opt;
4936 struct MHD_OptionItem *oa; 4938 struct MHD_OptionItem *oa;
@@ -6493,10 +6495,10 @@ thread_failed:
6493 if (daemon->upgrade_fd_in_epoll) 6495 if (daemon->upgrade_fd_in_epoll)
6494 { 6496 {
6495 if (0 != epoll_ctl (daemon->epoll_fd, 6497 if (0 != epoll_ctl (daemon->epoll_fd,
6496 EPOLL_CTL_DEL, 6498 EPOLL_CTL_DEL,
6497 daemon->epoll_upgrade_fd, 6499 daemon->epoll_upgrade_fd,
6498 NULL)) 6500 NULL))
6499 MHD_PANIC (_("Failed to remove FD from epoll set\n")); 6501 MHD_PANIC (_("Failed to remove FD from epoll set\n"));
6500 daemon->upgrade_fd_in_epoll = false; 6502 daemon->upgrade_fd_in_epoll = false;
6501 } 6503 }
6502#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 6504#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */