diff options
author | Christian Grothoff <christian@grothoff.org> | 2016-11-13 19:19:20 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2016-11-13 19:19:20 +0100 |
commit | d95ee55386fd05a14e9439f0b798ddd2b185b540 (patch) | |
tree | 7e5624ddf3a2be4256df19dc401c3054bd9ae9cf | |
parent | 53673f6b2174dd752abde08c0181093e9aca7b71 (diff) | |
download | libmicrohttpd-d95ee55386fd05a14e9439f0b798ddd2b185b540.tar.gz libmicrohttpd-d95ee55386fd05a14e9439f0b798ddd2b185b540.zip |
fixes to fix Doppelbauer testcase
-rw-r--r-- | src/microhttpd/connection.c | 30 | ||||
-rw-r--r-- | src/microhttpd/daemon.c | 21 |
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, | |||
2343 | void | 2343 | void |
2344 | MHD_suspend_connection (struct MHD_Connection *connection) | 2344 | MHD_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); |