summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorPaul Querna <pquerna@apache.org>2008-10-30 11:46:58 +0100
committerPaul Querna <pquerna@apache.org>2008-10-30 11:46:58 +0100
commit9c0569735d281ae858fd96d6be1d3833a895407d (patch)
treef67d5c97012536c20fb3bafa0681de6e11343944 /server
parentAdd Makefile.in, so unixd will actually compile correctly :-). (diff)
downloadapache2-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.c78
-rw-r--r--server/mpm/simple/simple_core.c2
-rw-r--r--server/mpm/simple/simple_run.c1
-rw-r--r--server/mpm/simple/simple_types.h19
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;