]> granicus.if.org Git - apache/commitdiff
Exit threads early during shutdown, part 2
authorStefan Fritsch <sf@apache.org>
Sun, 10 Apr 2016 22:53:42 +0000 (22:53 +0000)
committerStefan Fritsch <sf@apache.org>
Sun, 10 Apr 2016 22:53:42 +0000 (22:53 +0000)
Follow up to r1738466: During graceful shutdown, when the listener thread is
closing a connection, it needs to wake up a worker thread so that it may
terminate.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1738486 13f79535-47bb-0310-9956-ffa450edef68

server/mpm/event/event.c
server/mpm/event/fdqueue.c
server/mpm/event/fdqueue.h

index a3a709862e7bce772d8fcc4f8a7a5d9564879df7..4c4853f8565aab80331be21d77af778d05184718 100644 (file)
@@ -950,6 +950,8 @@ static int start_lingering_close_nonblocking(event_conn_state_t *cs)
         || apr_socket_shutdown(csd, APR_SHUTDOWN_WRITE) != APR_SUCCESS) {
         apr_socket_close(csd);
         ap_push_pool(worker_queue_info, cs->p);
+        if (dying)
+            ap_queue_interrupt_one(worker_queue);
         return 0;
     }
     return start_lingering_close_common(cs, 0);
@@ -973,6 +975,8 @@ static int stop_lingering_close(event_conn_state_t *cs)
         AP_DEBUG_ASSERT(0);
     }
     ap_push_pool(worker_queue_info, cs->p);
+    if (dying)
+        ap_queue_interrupt_one(worker_queue);
     return 0;
 }
 
@@ -1645,6 +1649,8 @@ static void process_lingering_close(event_conn_state_t *cs, const apr_pollfd_t *
     TO_QUEUE_ELEM_INIT(cs);
 
     ap_push_pool(worker_queue_info, cs->p);
+    if (dying)
+        ap_queue_interrupt_one(worker_queue);
 }
 
 /* call 'func' for all elements of 'q' with timeout less than 'timeout_time'.
index 75b79047b227e8cd92ed800dde572bd130f4c373..7775a157d04a5343ecfc7aff3df9d17974f152f1 100644 (file)
@@ -487,7 +487,7 @@ apr_status_t ap_queue_pop_something(fd_queue_t * queue, apr_socket_t ** sd,
     return rv;
 }
 
-static apr_status_t queue_interrupt_all(fd_queue_t *queue, int term)
+static apr_status_t queue_interrupt(fd_queue_t *queue, int all, int term)
 {
     apr_status_t rv;
 
@@ -501,16 +501,24 @@ static apr_status_t queue_interrupt_all(fd_queue_t *queue, int term)
     if (term) {
         queue->terminated = 1;
     }
-    apr_thread_cond_broadcast(queue->not_empty);
+    if (all)
+        apr_thread_cond_broadcast(queue->not_empty);
+    else
+        apr_thread_cond_signal(queue->not_empty);
     return apr_thread_mutex_unlock(queue->one_big_mutex);
 }
 
 apr_status_t ap_queue_interrupt_all(fd_queue_t * queue)
 {
-    return queue_interrupt_all(queue, 0);
+    return queue_interrupt(queue, 1, 0);
+}
+
+apr_status_t ap_queue_interrupt_one(fd_queue_t * queue)
+{
+    return queue_interrupt(queue, 0, 0);
 }
 
 apr_status_t ap_queue_term(fd_queue_t * queue)
 {
-    return queue_interrupt_all(queue, 1);
+    return queue_interrupt(queue, 1, 1);
 }
index 00059d3563e57f1b81c2ef080c52c6a8456a7c16..df54217387566e826f37dd0f97d1faee6dc70e50 100644 (file)
@@ -101,6 +101,7 @@ apr_status_t ap_queue_pop_something(fd_queue_t * queue, apr_socket_t ** sd,
                                     event_conn_state_t ** ecs, apr_pool_t ** p,
                                     timer_event_t ** te);
 apr_status_t ap_queue_interrupt_all(fd_queue_t * queue);
+apr_status_t ap_queue_interrupt_one(fd_queue_t * queue);
 apr_status_t ap_queue_term(fd_queue_t * queue);
 
 #endif /* FDQUEUE_H */