diff options
author | Paul Querna <pquerna@apache.org> | 2008-10-30 11:46:58 +0100 |
---|---|---|
committer | Paul Querna <pquerna@apache.org> | 2008-10-30 11:46:58 +0100 |
commit | 9c0569735d281ae858fd96d6be1d3833a895407d (patch) | |
tree | f67d5c97012536c20fb3bafa0681de6e11343944 /server | |
parent | Add Makefile.in, so unixd will actually compile correctly :-). (diff) | |
download | apache2-9c0569735d281ae858fd96d6be1d3833a895407d.tar.xz apache2-9c0569735d281ae858fd96d6be1d3833a895407d.zip |
Basic support for spawning children porcesses via fork() and killing them with kill().
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@709136 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'server')
-rw-r--r-- | server/mpm/simple/simple_children.c | 78 | ||||
-rw-r--r-- | server/mpm/simple/simple_core.c | 2 | ||||
-rw-r--r-- | server/mpm/simple/simple_run.c | 1 | ||||
-rw-r--r-- | server/mpm/simple/simple_types.h | 19 |
4 files changed, 88 insertions, 12 deletions
diff --git a/server/mpm/simple/simple_children.c b/server/mpm/simple/simple_children.c index cf09d21ff9..bfa1a7657e 100644 --- a/server/mpm/simple/simple_children.c +++ b/server/mpm/simple/simple_children.c @@ -19,32 +19,95 @@ #include "simple_types.h" #include "simple_event.h" #include "simple_run.h" +#include "http_log.h" #include "simple_children.h" #include "apr_hash.h" +#include <unistd.h> /* For fork() */ + #define SPAWN_CHILDREN_INTERVAL (apr_time_from_sec(5)) static void simple_kill_random_child(simple_core_t * sc) { - apr_thread_mutex_lock(sc->mtx); /* See comment in simple_spawn_child for why we check here. */ if (!sc->run_single_process) { + apr_hash_index_t *hi; + simple_child_t *child = NULL; + + apr_thread_mutex_lock(sc->mtx); + hi = apr_hash_first(sc->pool, sc->children); + if (hi != NULL) { + apr_hash_this(hi, NULL, NULL, (void **)&child); + apr_hash_set(sc->children, &child->pid, sizeof(child->pid), NULL); + } + apr_thread_mutex_unlock(sc->mtx); + + if (child != NULL) { + kill(child->pid, 9); + /* TODO: recycle child object */ + } } - apr_thread_mutex_unlock(sc->mtx); } -static void simple_spawn_child(simple_core_t * sc) +static void clean_child_exit(int code) __attribute__ ((noreturn)); +static void clean_child_exit(int code) +{ + /* TODO: Pool cleanups.... sigh. */ + exit(code); +} + +static int simple_spawn_child(simple_core_t * sc) { - apr_thread_mutex_lock(sc->mtx); + pid_t pid = 0; + int rv = 0; /* Although we could cut this off 'earlier', and not even invoke this * function, I would like to keep the functions invoked when in debug mode * to be as close as possible to those when not in debug... So, we just skip * the actual spawn itself, but go through all of the motions... */ if (!sc->run_single_process) { + if (sc->spawn_via == SIMPLE_SPAWN_FORK) { + + pid = fork(); + if (pid == -1) { + rv = errno; + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, + "simple_spawn_child: Unable to fork new process"); + return rv; + } + + if (pid == 0) { + /* this is the child process */ + + rv = simple_child_loop(sc); + if (rv) { + clean_child_exit(APEXIT_CHILDFATAL); + } + else { + clean_child_exit(0); + } + } + } + else { + /* TODO: SIMPLE_SPAWN_EXEC */ + abort(); + } + } + + if (pid != 0) { + simple_child_t *child; + + apr_thread_mutex_lock(sc->mtx); + + child = apr_palloc(sc->pool, sizeof(simple_child_t)); + child->pid = pid; + apr_hash_set(sc->children, &child->pid, sizeof(child->pid), child); + + apr_thread_mutex_unlock(sc->mtx); } - apr_thread_mutex_unlock(sc->mtx); + + return 0; } void simple_check_children_size(simple_core_t * sc, void *baton) @@ -83,10 +146,11 @@ void simple_check_children_size(simple_core_t * sc, void *baton) } } else if (count < wanted) { + int rv = 0; /* spawn some kids */ int to_spawn = wanted - count; - for (i = 0; i < to_spawn; i++) { - simple_spawn_child(sc); + for (i = 0; rv == 0 && i < to_spawn; i++) { + rv = simple_spawn_child(sc); } } else { diff --git a/server/mpm/simple/simple_core.c b/server/mpm/simple/simple_core.c index 391bd42433..3e4f228a79 100644 --- a/server/mpm/simple/simple_core.c +++ b/server/mpm/simple/simple_core.c @@ -49,6 +49,8 @@ apr_status_t simple_core_init(simple_core_t * sc, apr_pool_t * pool) sc->procmgr.max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD; sc->children = apr_hash_make(sc->pool); + /* TODO: configurable spawning mech */ + sc->spawn_via = SIMPLE_SPAWN_FORK; APR_RING_INIT(&sc->timer_ring, simple_timer_t, link); APR_RING_INIT(&sc->dead_timer_ring, simple_timer_t, link); diff --git a/server/mpm/simple/simple_run.c b/server/mpm/simple/simple_run.c index 0256173a6c..691c27523a 100644 --- a/server/mpm/simple/simple_run.c +++ b/server/mpm/simple/simple_run.c @@ -138,6 +138,7 @@ static void *simple_timer_invoke(apr_thread_t * thread, void *baton) ep->cb(sc, ep->baton); apr_thread_mutex_lock(sc->mtx); + APR_RING_ELEM_INIT(ep, link); APR_RING_INSERT_TAIL(&sc->dead_timer_ring, ep, simple_timer_t, link); apr_thread_mutex_unlock(sc->mtx); diff --git a/server/mpm/simple/simple_types.h b/server/mpm/simple/simple_types.h index 6061391d5d..f88d6028c4 100644 --- a/server/mpm/simple/simple_types.h +++ b/server/mpm/simple/simple_types.h @@ -35,11 +35,6 @@ typedef struct int max_requests_per_child; } simple_proc_mgr_t; -typedef struct -{ - int pid; -} simple_child_t; - typedef void (*simple_timer_cb) (simple_core_t * sc, void *baton); typedef void (*simple_io_sock_cb) (simple_core_t * sc, apr_socket_t * sock, int flags, void *baton); @@ -56,6 +51,12 @@ typedef enum SIMPLE_PT_USER } simple_poll_type_e; +typedef enum +{ + SIMPLE_SPAWN_FORK, + SIMPLE_SPAWN_EXEC, +} simple_spawn_type_e; + struct simple_sb_t { simple_poll_type_e type; @@ -71,6 +72,13 @@ struct simple_timer_t void *baton; }; +typedef struct simple_child_t simple_child_t; +struct simple_child_t +{ + /* TODO: More is needed here. */ + pid_t pid; +}; + struct simple_core_t { apr_pool_t *pool; @@ -81,6 +89,7 @@ struct simple_core_t int run_single_process; int run_foreground; + simple_spawn_type_e spawn_via; simple_proc_mgr_t procmgr; |