diff options
author | Stefan Fritsch <sf@apache.org> | 2011-06-18 15:21:20 +0200 |
---|---|---|
committer | Stefan Fritsch <sf@apache.org> | 2011-06-18 15:21:20 +0200 |
commit | 0bb879b92b84ae4a6720294ee5221411425aa3cb (patch) | |
tree | 7a3c4908f0f4482db9b09c53700f6e0e2eb3ad2e /server/mpm/event/event.c | |
parent | s/seperate/separate/ (diff) | |
download | apache2-0bb879b92b84ae4a6720294ee5221411425aa3cb.tar.xz apache2-0bb879b92b84ae4a6720294ee5221411425aa3cb.zip |
Fix graceful restart aborting connections
PR: 43359
Submitted by: Takashi Sato <takashi lans-tv com>
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1137182 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to '')
-rw-r--r-- | server/mpm/event/event.c | 72 |
1 files changed, 53 insertions, 19 deletions
diff --git a/server/mpm/event/event.c b/server/mpm/event/event.c index 4efcc903a6..066d9b6f52 100644 --- a/server/mpm/event/event.c +++ b/server/mpm/event/event.c @@ -54,6 +54,7 @@ #include "apr_poll.h" #include "apr_ring.h" #include "apr_queue.h" +#include "apr_atomic.h" #define APR_WANT_STRFUNC #include "apr_want.h" #include "apr_version.h" @@ -502,6 +503,13 @@ static int child_fatal; /* volatile because they're updated from a signal handler */ static int volatile shutdown_pending; static int volatile restart_pending; +ap_generation_t volatile ap_my_generation = 0; +static apr_uint32_t connection_count = 0; + +static apr_status_t decrement_connection_count(void *dummy){ + apr_atomic_dec32(&connection_count); + return APR_SUCCESS; +} /* * ap_start_shutdown() and ap_start_restart(), below, are a first stab at @@ -671,6 +679,8 @@ static int process_socket(apr_thread_t *thd, apr_pool_t * p, apr_socket_t * sock cs->bucket_alloc = apr_bucket_alloc_create(p); c = ap_run_create_connection(p, ap_server_conf, sock, conn_id, sbh, cs->bucket_alloc); + apr_atomic_inc32(&connection_count); + apr_pool_cleanup_register(c->pool, NULL, decrement_connection_count, apr_pool_cleanup_null); c->current_thread = thd; cs->c = c; c->cs = cs; @@ -832,6 +842,29 @@ static void check_infinite_requests(void) } } +static void close_listeners(int process_slot, int *closed) { + if (!*closed){ + ap_listen_rec *lr; + int i; + for (lr = ap_listeners; lr != NULL; lr = lr->next) { + apr_pollfd_t *pfd = apr_pcalloc(pchild, sizeof(*pfd)); + pfd->desc_type = APR_POLL_SOCKET; + pfd->desc.s = lr->sd; + apr_pollset_remove(event_pollset, pfd); + } + ap_close_listeners(); + *closed = 1; + dying = 1; + ap_scoreboard_image->parent[process_slot].quiescing = 1; + for (i = 0; i < threads_per_child; ++i){ + ap_update_child_status_from_indexes(process_slot, i, + SERVER_DEAD, NULL); + } + /* wake up the main thread */ + kill(ap_my_pid, SIGTERM); + } +} + static void unblock_signal(int sig) { sigset_t sig_mask; @@ -1082,6 +1115,7 @@ static void * APR_THREAD_FUNC listener_thread(apr_thread_t * thd, void *dummy) apr_interval_time_t timeout_interval; apr_time_t timeout_time; listener_poll_type *pt; + int closed = 0; free(ti); @@ -1108,7 +1142,13 @@ static void * APR_THREAD_FUNC listener_thread(apr_thread_t * thd, void *dummy) unblock_signal(LISTENER_SIGNAL); apr_signal(LISTENER_SIGNAL, dummy_signal_handler); - while (!listener_may_exit) { + for (;;) { + if (listener_may_exit){ + close_listeners(process_slot, &closed); + if (terminate_mode == ST_UNGRACEFUL + || apr_atomic_read32(&connection_count) == 0) + break; + } if (requests_this_child <= 0) { check_infinite_requests(); @@ -1156,8 +1196,13 @@ static void * APR_THREAD_FUNC listener_thread(apr_thread_t * thd, void *dummy) } } - if (listener_may_exit) - break; + if (listener_may_exit){ + close_listeners(process_slot, &closed); + if (terminate_mode == ST_UNGRACEFUL || + apr_atomic_read32(&connection_count) == 0) { + break; + } + } { apr_time_t now = apr_time_now(); @@ -1353,13 +1398,8 @@ static void * APR_THREAD_FUNC listener_thread(apr_thread_t * thd, void *dummy) } /* listener main loop */ - ap_close_listeners(); + close_listeners(process_slot, &closed); ap_queue_term(worker_queue); - dying = 1; - ap_scoreboard_image->parent[process_slot].quiescing = 1; - - /* wake up the main thread */ - kill(ap_my_pid, SIGTERM); apr_thread_exit(thd, APR_SUCCESS); return NULL; @@ -1406,7 +1446,7 @@ static void *APR_THREAD_FUNC worker_thread(apr_thread_t * thd, void *dummy) } ap_update_child_status_from_indexes(process_slot, thread_slot, - SERVER_READY, NULL); + dying ? SERVER_DEAD : SERVER_READY, NULL); worker_pop: if (workers_may_exit) { break; @@ -1664,21 +1704,15 @@ static void join_workers(apr_thread_t * listener, apr_thread_t ** threads) */ iter = 0; - while (iter < 10 && -#ifdef HAVE_PTHREAD_KILL - pthread_kill(*listener_os_thread, 0) -#else - kill(ap_my_pid, 0) -#endif - == 0) { - /* listener not dead yet */ + while (iter < 10 && !dying) { + /* listener has not stopped accepting yet */ apr_sleep(apr_time_make(0, 500000)); wakeup_listener(); ++iter; } if (iter >= 10) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, - "the listener thread didn't exit"); + "the listener thread didn't stop accepting"); } else { rv = apr_thread_join(&thread_rv, listener); |