You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by tr...@apache.org on 2002/03/21 20:12:54 UTC
cvs commit: httpd-2.0/server/mpm/worker fdqueue.c fdqueue.h worker.c
trawick 02/03/21 11:12:54
Modified: . CHANGES
server/mpm/worker fdqueue.c fdqueue.h worker.c
Log:
Don't drop connections during graceful restart. Previously, worker
threads could exit even though there were connections waiting in the
queue.
Now, for a graceful restart the worker threads won't exit until they
are told that the queue has been drained and no more connections will
ever be added.
Revision Changes Path
1.651 +3 -0 httpd-2.0/CHANGES
Index: CHANGES
===================================================================
RCS file: /home/cvs/httpd-2.0/CHANGES,v
retrieving revision 1.650
retrieving revision 1.651
diff -u -r1.650 -r1.651
--- CHANGES 21 Mar 2002 12:05:45 -0000 1.650
+++ CHANGES 21 Mar 2002 19:12:54 -0000 1.651
@@ -1,5 +1,8 @@
Changes with Apache 2.0.34-dev
+ *) Fix some restart/terminate problems in the worker MPM. Don't
+ drop connections during graceful restart. [Jeff Trawick]
+
*) Change the header merging behaviour in proxy, as some headers
(like Set-Cookie) cannot be unmerged due to stray commas in
dates. [Graham Leggett]
1.14 +28 -2 httpd-2.0/server/mpm/worker/fdqueue.c
Index: fdqueue.c
===================================================================
RCS file: /home/cvs/httpd-2.0/server/mpm/worker/fdqueue.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- fdqueue.c 21 Mar 2002 15:27:31 -0000 1.13
+++ fdqueue.c 21 Mar 2002 19:12:54 -0000 1.14
@@ -140,6 +140,8 @@
return rv;
}
+ AP_DEBUG_ASSERT(!queue->terminated);
+
while (ap_queue_full(queue)) {
apr_thread_cond_wait(queue->not_full, queue->one_big_mutex);
}
@@ -191,13 +193,20 @@
/* Keep waiting until we wake up and find that the queue is not empty. */
if (ap_queue_empty(queue)) {
- apr_thread_cond_wait(queue->not_empty, queue->one_big_mutex);
+ if (!queue->terminated) {
+ apr_thread_cond_wait(queue->not_empty, queue->one_big_mutex);
+ }
/* If we wake up and it's still empty, then we were interrupted */
if (ap_queue_empty(queue)) {
if ((rv = apr_thread_mutex_unlock(queue->one_big_mutex)) != APR_SUCCESS) {
return rv;
}
- return APR_EINTR;
+ if (queue->terminated) {
+ return APR_EOF; /* no more elements ever again */
+ }
+ else {
+ return APR_EINTR;
+ }
}
}
@@ -236,3 +245,20 @@
return APR_SUCCESS;
}
+apr_status_t ap_queue_term(fd_queue_t *queue)
+{
+ apr_status_t rv;
+
+ if ((rv = apr_thread_mutex_lock(queue->one_big_mutex)) != APR_SUCCESS) {
+ return rv;
+ }
+ /* we must hold one_big_mutex when setting this... otherwise,
+ * we could end up setting it and waking everybody up just after a
+ * would-be popper checks it but right before they block
+ */
+ queue->terminated = 1;
+ if ((rv = apr_thread_mutex_unlock(queue->one_big_mutex)) != APR_SUCCESS) {
+ return rv;
+ }
+ return ap_queue_interrupt_all(queue);
+}
1.15 +2 -0 httpd-2.0/server/mpm/worker/fdqueue.h
Index: fdqueue.h
===================================================================
RCS file: /home/cvs/httpd-2.0/server/mpm/worker/fdqueue.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- fdqueue.h 21 Mar 2002 15:19:54 -0000 1.14
+++ fdqueue.h 21 Mar 2002 19:12:54 -0000 1.15
@@ -86,6 +86,7 @@
apr_thread_cond_t *not_full;
apr_pool_t **recycled_pools;
int num_recycled;
+ int terminated;
};
typedef struct fd_queue_t fd_queue_t;
@@ -95,5 +96,6 @@
apr_status_t ap_queue_pop(fd_queue_t *queue, apr_socket_t **sd, apr_pool_t **p,
apr_pool_t *recycled_pool);
apr_status_t ap_queue_interrupt_all(fd_queue_t *queue);
+apr_status_t ap_queue_term(fd_queue_t *queue);
#endif /* FDQUEUE_H */
1.104 +23 -3 httpd-2.0/server/mpm/worker/worker.c
Index: worker.c
===================================================================
RCS file: /home/cvs/httpd-2.0/server/mpm/worker/worker.c,v
retrieving revision 1.103
retrieving revision 1.104
diff -u -r1.103 -r1.104
--- worker.c 21 Mar 2002 16:31:39 -0000 1.103
+++ worker.c 21 Mar 2002 19:12:54 -0000 1.104
@@ -267,17 +267,30 @@
static void signal_threads(int mode)
{
+ static int prev_mode = 0;
+
+ if (prev_mode == mode) {
+ return;
+ }
+ prev_mode = mode;
+
/* in case we weren't called from the listener thread, wake up the
* listener thread
*/
wakeup_listener();
+ /* for ungraceful termination, let the workers exit now;
+ * for graceful termination, the listener thread will notify the
+ * workers to exit once it has stopped accepting new connections
+ */
+ if (mode == ST_UNGRACEFUL) {
+ workers_may_exit = 1;
+ ap_queue_interrupt_all(worker_queue);
+ }
+
/* XXX: This will happen naturally on a graceful, and we don't care
* otherwise.
ap_queue_signal_all_wakeup(worker_queue); */
-
- workers_may_exit = 1;
- ap_queue_interrupt_all(worker_queue);
}
AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result)
@@ -798,6 +811,7 @@
ap_update_child_status_from_indexes(process_slot, thread_slot,
(dying) ? SERVER_DEAD : SERVER_GRACEFUL,
(request_rec *) NULL);
+ ap_queue_term(worker_queue);
dying = 1;
ap_scoreboard_image->parent[process_slot].quiescing = 1;
kill(ap_my_pid, SIGTERM);
@@ -832,6 +846,12 @@
last_ptrans = NULL;
if (rv != APR_SUCCESS) {
+ /* We get APR_EOF during a graceful shutdown once all the connections
+ * accepted by this server process have been handled.
+ */
+ if (rv == APR_EOF) {
+ break;
+ }
/* We get APR_EINTR whenever ap_queue_pop() has been interrupted
* from an explicit call to ap_queue_interrupt_all(). This allows
* us to unblock threads stuck in ap_queue_pop() when a shutdown
Re: cvs commit: httpd-2.0/server/mpm/worker fdqueue.c fdqueue.h worker.c
Posted by Jeff Trawick <tr...@attglobal.net>.
Aaron Bannert <aa...@clove.org> writes:
> Is ap_queue_interrupt_all() used anywhere externally anymore? Let's
> just get rid of it in lieu of ap_queue_term().
That one is still used by worker MPM on the non-graceful shutdown
path.
On my first attempt to get this working I had a parameter to
ap_queue_term() which told it whether or not to nuke the queue before
waking up the threads in ap_queue_pop(). If that were implemented
again then on the non-graceful shutdown path we could call
ap_queue_term(nuke-the-queue) instead of ap_queue_interrupt_all(),
and then we wouldn't need to externalize ap_queue_interrupt_all().
--
Jeff Trawick | trawick@attglobal.net
Born in Roswell... married an alien...
Re: cvs commit: httpd-2.0/server/mpm/worker fdqueue.c fdqueue.h worker.c
Posted by Aaron Bannert <aa...@clove.org>.
On Thu, Mar 21, 2002 at 07:12:54PM -0000, trawick@apache.org wrote:
> trawick 02/03/21 11:12:54
>
> Modified: . CHANGES
> server/mpm/worker fdqueue.c fdqueue.h worker.c
> Log:
> Don't drop connections during graceful restart. Previously, worker
> threads could exit even though there were connections waiting in the
> queue.
>
> Now, for a graceful restart the worker threads won't exit until they
> are told that the queue has been drained and no more connections will
> ever be added.
Awesome!
Is ap_queue_interrupt_all() used anywhere externally anymore? Let's
just get rid of it in lieu of ap_queue_term().
-aaron