]> TLD Linux GIT Repositories - packages/apache.git/blob - apache-bug-48094.patch
- mod_authn/z_core provide mod_authn/z_default to smooth upgrade
[packages/apache.git] / apache-bug-48094.patch
1 --- httpd-2.2.14-v/server/mpm/worker/worker.c   2007-07-18 00:48:25.000000000 +1000
2 +++ httpd-2.2.14/server/mpm/worker/worker.c     2009-11-02 09:40:23.129750043 +1100
3 @@ -32,6 +32,7 @@
4  #include "apr_poll.h"
5  #define APR_WANT_STRFUNC
6  #include "apr_want.h"
7 +#include "apr_atomic.h"
8  
9  #if APR_HAVE_UNISTD_H
10  #include <unistd.h>
11 @@ -226,10 +227,73 @@
12   */
13  #define WORKER_SIGNAL       AP_SIG_GRACEFUL
14  
15 +#ifdef HAVE_PTHREAD_KILL
16 +/* Variables for suspending the worker threads. */
17 +static volatile sig_atomic_t suspend_workers = 0;
18 +static apr_uint32_t suspended_workers;
19 +static apr_os_thread_t **worker_os_threads;
20 +#endif
21 +
22  /* An array of socket descriptors in use by each thread used to
23   * perform a non-graceful (forced) shutdown of the server. */
24  static apr_socket_t **worker_sockets;
25  
26 +#ifdef HAVE_PTHREAD_KILL
27 +static void worker_signal_handler(int sig)
28 +{
29 +    /* wait here if we are being suspended, otherwise just exit */
30 +    if (suspend_workers) {
31 +        sigset_t sigset;
32 +
33 +        apr_atomic_inc32(&suspended_workers);
34 +
35 +        sigfillset(&sigset);
36 +        sigdelset(&sigset, WORKER_SIGNAL);
37 +        sigsuspend(&sigset);
38 +    }
39 +}
40 +
41 +static void close_worker_sockets(void)
42 +{
43 +    int i, csd;
44 +
45 +    suspend_workers = 1;
46 +    apr_atomic_set32(&suspended_workers, 0);
47 +
48 +    /* suspend worker threads */
49 +    for (i = 0; i < ap_threads_per_child; i++) {
50 +        if (worker_os_threads[i]) {
51 +            pthread_kill(*worker_os_threads[i], WORKER_SIGNAL);
52 +        }
53 +    }
54 +
55 +    /* wait for threads to suspend, but press ahead after a while anyway */
56 +    for (i = 0;
57 +         apr_atomic_read32(&suspended_workers) < ap_threads_per_child && i < 25;
58 +         i++) {
59 +        apr_sleep(apr_time_from_sec(1) / 5);
60 +    }
61 +
62 +    /* shut down all client sockets */
63 +    for (i = 0; i < ap_threads_per_child; i++) {
64 +        if (worker_sockets[i]) {
65 +            apr_os_sock_get(&csd, worker_sockets[i]);
66 +            if (csd != -1) {
67 +                shutdown(csd, SHUT_RDWR);
68 +            }
69 +        }
70 +    }
71 +
72 +    suspend_workers = 0;
73 +
74 +    /* resume worker threads */
75 +    for (i = 0; i < ap_threads_per_child; i++) {
76 +        if (worker_os_threads[i]) {
77 +            pthread_kill(*worker_os_threads[i], WORKER_SIGNAL);
78 +        }
79 +    }
80 +}
81 +#else
82  static void close_worker_sockets(void)
83  {
84      int i;
85 @@ -240,6 +304,7 @@
86          }
87      }
88  }
89 +#endif
90  
91  static void wakeup_listener(void)
92  {
93 @@ -836,7 +901,7 @@
94  
95  #ifdef HAVE_PTHREAD_KILL
96      unblock_signal(WORKER_SIGNAL);
97 -    apr_signal(WORKER_SIGNAL, dummy_signal_handler);
98 +    apr_signal(WORKER_SIGNAL, worker_signal_handler);
99  #endif
100  
101      while (!workers_may_exit) {
102 @@ -977,6 +1042,10 @@
103  
104      worker_sockets = apr_pcalloc(pchild, ap_threads_per_child
105                                          * sizeof(apr_socket_t *));
106 +#ifdef HAVE_PTHREAD_KILL
107 +    worker_os_threads = apr_pcalloc(pchild, ap_threads_per_child
108 +                                           * sizeof(*worker_os_threads));
109 +#endif
110  
111      loops = prev_threads_created = 0;
112      while (1) {
113 @@ -1012,6 +1081,9 @@
114                  /* let the parent decide how bad this really is */
115                  clean_child_exit(APEXIT_CHILDSICK);
116              }
117 +#ifdef HAVE_PTHREAD_KILL
118 +            apr_os_thread_get(&worker_os_threads[i], threads[i]);
119 +#endif
120              threads_created++;
121          }
122          /* Start the listener only when there are workers available */