ASF Bugzilla – Attachment 24449 Details for
Bug 48094
Avoid a race condition in close_worker_sockets()
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
(Hopefully) safe close_worker_sockets()
safe_close_worker_sockets-trunk.patch (text/plain), 4.41 KB, created by
Bojan Smojver
on 2009-11-01 00:42:20 UTC
(
hide
)
Description:
(Hopefully) safe close_worker_sockets()
Filename:
MIME Type:
Creator:
Bojan Smojver
Created:
2009-11-01 00:42:20 UTC
Size:
4.41 KB
patch
obsolete
>Index: server/mpm/worker/worker.c >=================================================================== >--- server/mpm/worker/worker.c (revision 831647) >+++ server/mpm/worker/worker.c (working copy) >@@ -233,12 +233,97 @@ > */ > #define WORKER_SIGNAL AP_SIG_GRACEFUL > >+#ifdef HAVE_PTHREAD_KILL >+/* An array of thread and socket descriptors in use by each thread used to >+ * perform a non-graceful (forced) shutdown of the server. */ >+static volatile sig_atomic_t suspend_workers = 0; >+static struct worker_data { >+ apr_os_thread_t *thread; >+ apr_socket_t *socket; >+ volatile sig_atomic_t suspended; >+} *worker_data; >+#else > /* An array of socket descriptors in use by each thread used to > * perform a non-graceful (forced) shutdown of the server. */ > static apr_socket_t **worker_sockets; >+#endif > >+#ifdef HAVE_PTHREAD_KILL >+static void worker_signal_handler(int sig) >+{ >+ int i; >+ >+ /* find our thread */ >+ for (i = 0; i < threads_per_child; i++) { >+ if (worker_data[i].thread && >+ pthread_equal(*worker_data[i].thread, pthread_self())) { >+ break; >+ } >+ } >+ >+ /* just in case we overshot */ >+ if (i >= threads_per_child) { >+ return; >+ } >+ >+ /* suspend and then wait to resume */ >+ if (suspend_workers) { >+ worker_data[i].suspended = 1; >+ >+ while (suspend_workers) { >+ apr_sleep(SCOREBOARD_MAINTENANCE_INTERVAL / 5); >+ } >+ } >+ >+ worker_data[i].suspended = 0; >+} >+ > static void close_worker_sockets(void) > { >+ int i, j, csd; >+ >+ suspend_workers = 1; >+ >+ /* interrupt worker threads */ >+ for (i = 0; i < threads_per_child; i++) { >+ if (worker_data[i].thread) { >+ /* try sending the signal twice */ >+ if (pthread_kill(*worker_data[i].thread, WORKER_SIGNAL) == -1) { >+ pthread_kill(*worker_data[i].thread, WORKER_SIGNAL); >+ } >+ } >+ } >+ >+ /* wait for threads to suspend, but press ahead after a while anyway */ >+ for (j = 0; j < 25; j++) { >+ int sum = 0; >+ >+ apr_sleep(SCOREBOARD_MAINTENANCE_INTERVAL / 5); >+ >+ for (i = 0; i < threads_per_child; i++) { >+ sum += worker_data[i].suspended; >+ } >+ >+ if (sum == threads_per_child) { >+ break; >+ } >+ } >+ >+ /* shut down all client sockets */ >+ for (i = 0; i < threads_per_child; i++) { >+ if (worker_data[i].socket) { >+ apr_os_sock_get(&csd, worker_data[i].socket); >+ if (csd != -1) { >+ shutdown(csd, SHUT_RDWR); >+ } >+ } >+ } >+ >+ suspend_workers = 0; >+} >+#else >+static void close_worker_sockets(void) >+{ > int i; > for (i = 0; i < threads_per_child; i++) { > if (worker_sockets[i]) { >@@ -247,6 +332,7 @@ > } > } > } >+#endif > > static void wakeup_listener(void) > { >@@ -862,7 +948,7 @@ > > #ifdef HAVE_PTHREAD_KILL > unblock_signal(WORKER_SIGNAL); >- apr_signal(WORKER_SIGNAL, dummy_signal_handler); >+ apr_signal(WORKER_SIGNAL, worker_signal_handler); > #endif > > while (!workers_may_exit) { >@@ -915,10 +1001,22 @@ > continue; > } > is_idle = 0; >+ >+#ifdef HAVE_PTHREAD_KILL >+ worker_data[thread_slot].socket = csd; >+#else > worker_sockets[thread_slot] = csd; >+#endif >+ > bucket_alloc = apr_bucket_alloc_create(ptrans); > process_socket(thd, ptrans, csd, process_slot, thread_slot, bucket_alloc); >+ >+#ifdef HAVE_PTHREAD_KILL >+ worker_data[thread_slot].socket = NULL; >+#else > worker_sockets[thread_slot] = NULL; >+#endif >+ > requests_this_child--; > apr_pool_clear(ptrans); > last_ptrans = ptrans; >@@ -1001,8 +1099,13 @@ > clean_child_exit(APEXIT_CHILDFATAL); > } > >+#ifdef HAVE_PTHREAD_KILL >+ worker_data = apr_pcalloc(pchild, threads_per_child >+ * sizeof(*worker_data)); >+#else > worker_sockets = apr_pcalloc(pchild, threads_per_child > * sizeof(apr_socket_t *)); >+#endif > > loops = prev_threads_created = 0; > while (1) { >@@ -1038,6 +1141,9 @@ > /* let the parent decide how bad this really is */ > clean_child_exit(APEXIT_CHILDSICK); > } >+#ifdef HAVE_PTHREAD_KILL >+ apr_os_thread_get(&worker_data[i].thread, threads[i]); >+#endif > threads_created++; > } > /* Start the listener only when there are workers available */
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 48094
:
24449
|
24450
|
24453
|
24454
|
24510
|
24511