On Wed, Jul 11, 2001 at 07:44:14AM -0700, [EMAIL PROTECTED] wrote:
>
> The threaded MPM should use the POD calls from mpm_common.c, but they were
> added after the threaded MPM was written, and I never bothered to port
> it when I wrote the pod code.
>
> Ryan
Completely untested. Well, it compiles.
The only disadvantage is that since we aren't doing a select on the pod,
we have to check every time, but now that check isn't an exclusive
operation. So, it's probably a win just for that reason. =)
Since the mpm_common.c code has the correct call to file_read (i.e.
checks the return length), this should fix the problem with threaded
children dying too quickly. But, I can't reproduce it anyway, so it's
all theoretical from here. Someone who has this problem should see if
this fixes it. I bet it will. -- justin
Index: server/mpm/threaded/mpm.h
===================================================================
RCS file: /home/cvs/httpd-2.0/server/mpm/threaded/mpm.h,v
retrieving revision 1.5
diff -u -r1.5 mpm.h
--- server/mpm/threaded/mpm.h 2001/05/07 18:41:48 1.5
+++ server/mpm/threaded/mpm.h 2001/07/11 17:01:18
@@ -66,6 +66,7 @@
#define MPM_NAME "Threaded"
#define AP_MPM_NEEDS_RECLAIM_CHILD_PROCESSES 1
+#define AP_MPM_USES_POD 1
#define MPM_SYNC_CHILD_TABLE() (ap_sync_scoreboard_image())
#define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid)
#define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0)
Index: server/mpm/threaded/threaded.c
===================================================================
RCS file: /home/cvs/httpd-2.0/server/mpm/threaded/threaded.c,v
retrieving revision 1.44
diff -u -r1.44 threaded.c
--- server/mpm/threaded/threaded.c 2001/07/03 13:58:10 1.44
+++ server/mpm/threaded/threaded.c 2001/07/11 17:01:19
@@ -143,10 +143,7 @@
char ap_coredump_dir[MAX_STRING_LEN];
-static apr_file_t *pipe_of_death_in = NULL;
-static apr_file_t *pipe_of_death_out = NULL;
-static apr_lock_t *pipe_of_death_mutex; /* insures that a child process only
- consumes one character */
+static ap_pod_t *pipe_of_death;
/* *Non*-shared http_main globals... */
@@ -494,29 +491,6 @@
}
}
-/* Sets workers_may_exit if we received a character on the pipe_of_death */
-static void check_pipe_of_death(void)
-{
- apr_lock_acquire(pipe_of_death_mutex);
- if (!workers_may_exit) {
- apr_status_t ret;
- char pipe_read_char;
- apr_size_t n = 1;
-
- ret = apr_recv(listensocks[0], &pipe_read_char, &n);
- if (APR_STATUS_IS_EAGAIN(ret)) {
- /* It lost the lottery. It must continue to suffer
- * through a life of servitude. */
- }
- else {
- /* It won the lottery (or something else is very
- * wrong). Embrace death with open arms. */
- workers_may_exit = 1;
- }
- }
- apr_lock_release(pipe_of_death_mutex);
-}
-
static void * worker_thread(void * dummy)
{
proc_info * ti = dummy;
@@ -539,8 +513,8 @@
worker_thread_count++;
apr_lock_release(worker_thread_count_mutex);
- apr_poll_setup(&pollset, num_listensocks+1, tpool);
- for(n=0 ; n <= num_listensocks ; ++n)
+ apr_poll_setup(&pollset, num_listensocks, tpool);
+ for(n = 0; n < num_listensocks; ++n)
apr_poll_socket_add(pollset, listensocks[n], APR_POLLIN);
/* TODO: Switch to a system where threads reuse the results from earlier
@@ -580,12 +554,8 @@
if (workers_may_exit) break;
- apr_poll_revents_get(&event, listensocks[0], pollset);
- if (event & APR_POLLIN) {
- /* A process got a signal on the shutdown pipe. Check if we're
- * the lucky process to die. */
- check_pipe_of_death();
- continue;
+ if (!ap_mpm_pod_check(pipe_of_death)) {
+ workers_may_exit = 1;
}
if (num_listensocks == 1) {
@@ -780,12 +750,8 @@
}
/* Set up the pollfd array */
- listensocks = apr_pcalloc(pchild,
- sizeof(*listensocks) * (num_listensocks + 1));
-#if APR_FILES_AS_SOCKETS
- apr_socket_from_file(&listensocks[0], pipe_of_death_in);
-#endif
- for (lr = ap_listeners, i = 1; i <= num_listensocks; lr = lr->next, ++i)
+ listensocks = apr_pcalloc(pchild, sizeof(*listensocks) * num_listensocks);
+ for (lr = ap_listeners, i = 0; i < num_listensocks; lr = lr->next, ++i)
listensocks[i]=lr->sd;
/* Setup worker threads */
@@ -799,8 +765,6 @@
worker_thread_count = 0;
apr_lock_create(&worker_thread_count_mutex, APR_MUTEX, APR_INTRAPROCESS,
NULL, pchild);
- apr_lock_create(&pipe_of_death_mutex, APR_MUTEX, APR_INTRAPROCESS,
- NULL, pchild);
ts = apr_palloc(pchild, sizeof(*ts));
@@ -894,29 +858,6 @@
return 0;
}
-/* If there aren't many connections coming in from the network, the child
- * processes may need to be awakened from their network i/o waits.
- * The pipe of death is an effective prod.
- */
-
-static void wake_up_and_die(void)
-{
- int i;
- char char_of_death = '!';
- apr_size_t one = 1;
- apr_status_t rv;
-
- for (i = 0; i < ap_daemons_limit;) {
- if ((rv = apr_file_write(pipe_of_death_out, &char_of_death, &one))
- != APR_SUCCESS) {
- if (APR_STATUS_IS_EINTR(rv)) continue;
- ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf,
- "write pipe_of_death");
- }
- i++;
- }
-}
-
/* start up a bunch of children */
static void startup_children(int number_to_start)
{
@@ -955,8 +896,6 @@
int free_slots[MAX_SPAWN_RATE];
int last_non_dead;
int total_non_dead;
- apr_size_t one = 1;
- apr_status_t rv;
/* initialize the free_list */
free_length = 0;
@@ -1004,11 +943,7 @@
ap_max_daemons_limit = last_non_dead + 1;
if (idle_thread_count > max_spare_threads) {
- char char_of_death = '!';
- /* Kill off one child */
- if ((rv = apr_file_write(pipe_of_death_out, &char_of_death, &one)) !=
APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf, "write
pipe_of_death");
- }
+ ap_mpm_pod_signal(pipe_of_death);
idle_spawn_rate = 1;
}
else if (idle_thread_count < min_spare_threads) {
@@ -1129,18 +1064,11 @@
pconf = _pconf;
ap_server_conf = s;
- rv = apr_file_pipe_create(&pipe_of_death_in, &pipe_of_death_out, pconf);
+ rv = ap_mpm_pod_open(pconf, &pipe_of_death);
if (rv != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_ERR, rv,
- (const server_rec*) ap_server_conf,
- "apr_file_pipe_create (pipe_of_death)");
- exit(1);
- }
-
- if ((rv = apr_file_pipe_timeout_set(pipe_of_death_in, 0)) != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_ERR, rv,
(const server_rec*) ap_server_conf,
- "apr_file_pipe_timeout_set (pipe_of_death)");
+ "ap_mpm_pod_open");
exit(1);
}
@@ -1208,7 +1136,7 @@
/* Time to gracefully shut down:
* Kill child processes, tell them to call child_exit, etc...
*/
- wake_up_and_die();
+ ap_mpm_pod_killpg(pipe_of_death, ap_daemons_limit);
if (unixd_killpg(getpgrp(), SIGTERM) < 0) {
ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "killpg
SIGTERM");
@@ -1249,7 +1177,7 @@
update_scoreboard_global();
/* wake up the children...time to die. But we'll have more soon */
- wake_up_and_die();
+ ap_mpm_pod_killpg(pipe_of_death, ap_daemons_limit);
if (is_graceful) {
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0, ap_server_conf,