aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-11-13 19:19:20 +0100
committerChristian Grothoff <christian@grothoff.org>2016-11-13 19:19:20 +0100
commitd95ee55386fd05a14e9439f0b798ddd2b185b540 (patch)
tree7e5624ddf3a2be4256df19dc401c3054bd9ae9cf
parent53673f6b2174dd752abde08c0181093e9aca7b71 (diff)
downloadlibmicrohttpd-d95ee55386fd05a14e9439f0b798ddd2b185b540.tar.gz
libmicrohttpd-d95ee55386fd05a14e9439f0b798ddd2b185b540.zip
fixes to fix Doppelbauer testcase
-rw-r--r--src/microhttpd/connection.c30
-rw-r--r--src/microhttpd/daemon.c21
2 files changed, 37 insertions, 14 deletions
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index e634d4a8..d8b0f79d 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -2379,6 +2379,8 @@ update_last_activity (struct MHD_Connection *connection)
2379 connection->last_activity = MHD_monotonic_sec_counter(); 2379 connection->last_activity = MHD_monotonic_sec_counter();
2380 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) 2380 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2381 return; /* each connection has personal timeout */ 2381 return; /* each connection has personal timeout */
2382 if (connection->suspended)
2383 return; /* not timeouts for suspended connections */
2382 2384
2383 if (connection->connection_timeout != daemon->connection_timeout) 2385 if (connection->connection_timeout != daemon->connection_timeout)
2384 return; /* custom timeout, no need to move it in "normal" DLL */ 2386 return; /* custom timeout, no need to move it in "normal" DLL */
@@ -2541,7 +2543,6 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
2541 MHD_CONNECTION_HEADERS_SENT); 2543 MHD_CONNECTION_HEADERS_SENT);
2542 break; 2544 break;
2543 case MHD_CONNECTION_HEADERS_SENT: 2545 case MHD_CONNECTION_HEADERS_SENT:
2544 EXTRA_CHECK (0);
2545 break; 2546 break;
2546 case MHD_CONNECTION_NORMAL_BODY_READY: 2547 case MHD_CONNECTION_NORMAL_BODY_READY:
2547 response = connection->response; 2548 response = connection->response;
@@ -2663,9 +2664,11 @@ cleanup_connection (struct MHD_Connection *connection)
2663{ 2664{
2664 struct MHD_Daemon *daemon = connection->daemon; 2665 struct MHD_Daemon *daemon = connection->daemon;
2665 2666
2667 /* FIXME: when can this flag ever be needed? Sounds like we should
2668 avoid this happening in the first place. Also, could there then
2669 not be a race in this case? */
2666 if (connection->in_cleanup) 2670 if (connection->in_cleanup)
2667 return; /* Prevent double cleanup. */ 2671 return; /* Prevent double cleanup. */
2668
2669 connection->in_cleanup = true; 2672 connection->in_cleanup = true;
2670 if (NULL != connection->response) 2673 if (NULL != connection->response)
2671 { 2674 {
@@ -2685,17 +2688,21 @@ cleanup_connection (struct MHD_Connection *connection)
2685 connection); 2688 connection);
2686 } 2689 }
2687 if (connection->suspended) 2690 if (connection->suspended)
2688 DLL_remove (daemon->suspended_connections_head, 2691 {
2689 daemon->suspended_connections_tail, 2692 DLL_remove (daemon->suspended_connections_head,
2690 connection); 2693 daemon->suspended_connections_tail,
2694 connection);
2695 connection->suspended = false;
2696 }
2691 else 2697 else
2692 DLL_remove (daemon->connections_head, 2698 {
2693 daemon->connections_tail, 2699 DLL_remove (daemon->connections_head,
2694 connection); 2700 daemon->connections_tail,
2701 connection);
2702 }
2695 DLL_insert (daemon->cleanup_head, 2703 DLL_insert (daemon->cleanup_head,
2696 daemon->cleanup_tail, 2704 daemon->cleanup_tail,
2697 connection); 2705 connection);
2698 connection->suspended = false;
2699 connection->resuming = false; 2706 connection->resuming = false;
2700 connection->in_idle = false; 2707 connection->in_idle = false;
2701 MHD_mutex_unlock_chk_(&daemon->cleanup_connection_mutex); 2708 MHD_mutex_unlock_chk_(&daemon->cleanup_connection_mutex);
@@ -2739,6 +2746,11 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
2739 connection->in_idle = true; 2746 connection->in_idle = true;
2740 while (1) 2747 while (1)
2741 { 2748 {
2749 if (connection->suspended)
2750 {
2751 connection->in_idle = false;
2752 return MHD_YES;
2753 }
2742#if DEBUG_STATES 2754#if DEBUG_STATES
2743 MHD_DLOG (daemon, 2755 MHD_DLOG (daemon,
2744 _("In function %s handling connection at state: %s\n"), 2756 _("In function %s handling connection at state: %s\n"),
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index ffd2a5a7..caa72eef 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -2343,12 +2343,18 @@ internal_add_connection (struct MHD_Daemon *daemon,
2343void 2343void
2344MHD_suspend_connection (struct MHD_Connection *connection) 2344MHD_suspend_connection (struct MHD_Connection *connection)
2345{ 2345{
2346 struct MHD_Daemon *daemon; 2346 struct MHD_Daemon *daemon = connection->daemon;
2347 2347
2348 daemon = connection->daemon;
2349 if (MHD_ALLOW_SUSPEND_RESUME != (daemon->options & MHD_ALLOW_SUSPEND_RESUME)) 2348 if (MHD_ALLOW_SUSPEND_RESUME != (daemon->options & MHD_ALLOW_SUSPEND_RESUME))
2350 MHD_PANIC (_("Cannot suspend connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n")); 2349 MHD_PANIC (_("Cannot suspend connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
2351 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 2350 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
2351 if (connection->resuming)
2352 {
2353 /* suspending again while we didn't even complete resuming yet */
2354 connection->resuming = false;
2355 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
2356 return;
2357 }
2352 if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) 2358 if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2353 { 2359 {
2354 if (connection->connection_timeout == daemon->connection_timeout) 2360 if (connection->connection_timeout == daemon->connection_timeout)
@@ -2363,9 +2369,11 @@ MHD_suspend_connection (struct MHD_Connection *connection)
2363 DLL_remove (daemon->connections_head, 2369 DLL_remove (daemon->connections_head,
2364 daemon->connections_tail, 2370 daemon->connections_tail,
2365 connection); 2371 connection);
2372 EXTRA_CHECK (! connection->suspended);
2366 DLL_insert (daemon->suspended_connections_head, 2373 DLL_insert (daemon->suspended_connections_head,
2367 daemon->suspended_connections_tail, 2374 daemon->suspended_connections_tail,
2368 connection); 2375 connection);
2376 connection->suspended = true;
2369#ifdef EPOLL_SUPPORT 2377#ifdef EPOLL_SUPPORT
2370 if (0 != (daemon->options & MHD_USE_EPOLL)) 2378 if (0 != (daemon->options & MHD_USE_EPOLL))
2371 { 2379 {
@@ -2388,7 +2396,6 @@ MHD_suspend_connection (struct MHD_Connection *connection)
2388 connection->epoll_state |= MHD_EPOLL_STATE_SUSPENDED; 2396 connection->epoll_state |= MHD_EPOLL_STATE_SUSPENDED;
2389 } 2397 }
2390#endif 2398#endif
2391 connection->suspended = true;
2392 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 2399 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
2393} 2400}
2394 2401
@@ -2447,8 +2454,11 @@ resume_suspended_connections (struct MHD_Daemon *daemon)
2447 next = daemon->suspended_connections_head; 2454 next = daemon->suspended_connections_head;
2448 /* Clear the flag *only* if connections will be resumed otherwise 2455 /* Clear the flag *only* if connections will be resumed otherwise
2449 it may accidentally clear flag that was set at the same time in 2456 it may accidentally clear flag that was set at the same time in
2450 other thread (just after 'if (MHD_NO != daemon->resuming)' in 2457 another thread (just after 'if (MHD_NO != daemon->resuming)' in
2451 this thread). 2458 this thread).
2459
2460 FIXME: is this not prevented by the lock!?
2461
2452 Clear flag *before* resuming connections otherwise new connection can 2462 Clear flag *before* resuming connections otherwise new connection can
2453 be set to "resuming" in other thread, but missed resuming in this 2463 be set to "resuming" in other thread, but missed resuming in this
2454 function at this time so clearing flag at end will clear it without 2464 function at this time so clearing flag at end will clear it without
@@ -2472,9 +2482,11 @@ resume_suspended_connections (struct MHD_Daemon *daemon)
2472 ) 2482 )
2473 continue; 2483 continue;
2474 ret = MHD_YES; 2484 ret = MHD_YES;
2485 EXTRA_CHECK (pos->suspended);
2475 DLL_remove (daemon->suspended_connections_head, 2486 DLL_remove (daemon->suspended_connections_head,
2476 daemon->suspended_connections_tail, 2487 daemon->suspended_connections_tail,
2477 pos); 2488 pos);
2489 pos->suspended = false;
2478 if (NULL == urh) 2490 if (NULL == urh)
2479 { 2491 {
2480 DLL_insert (daemon->connections_head, 2492 DLL_insert (daemon->connections_head,
@@ -2518,7 +2530,6 @@ resume_suspended_connections (struct MHD_Daemon *daemon)
2518 2530
2519 } 2531 }
2520#endif /* UPGRADE_SUPPORT */ 2532#endif /* UPGRADE_SUPPORT */
2521 pos->suspended = false;
2522 pos->resuming = false; 2533 pos->resuming = false;
2523 } 2534 }
2524 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 2535 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);