From 905a83fc774aec277d2a2b9c9f605a0cca087aa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20B=C3=BChler?= Date: Sat, 13 Feb 2010 15:41:09 +0100 Subject: [PATCH] Add plugin hooks for server state machine changes --- include/lighttpd/plugin.h | 10 +++--- include/lighttpd/server.h | 1 - src/main/plugin.c | 73 +++++++++++++++++++++++++++++++++++---- src/main/server.c | 21 ++++++++--- 4 files changed, 89 insertions(+), 16 deletions(-) diff --git a/include/lighttpd/plugin.h b/include/lighttpd/plugin.h index bf0f3a3..6a50fb4 100644 --- a/include/lighttpd/plugin.h +++ b/include/lighttpd/plugin.h @@ -17,8 +17,8 @@ typedef liAction*(*liPluginCreateActionCB) (liServer *srv, liPlugin *p, liValue typedef gboolean (*liPluginSetupCB) (liServer *srv, liPlugin *p, liValue *val, gpointer userdata); typedef void (*liPluginAngelCB) (liServer *srv, liPlugin *p, gint32 id, GString *data); -typedef void (*liPluginServerPrepareWorker)(liServer *srv, liPlugin *p, liWorker *wrk); -typedef void (*liPluginServerPrepare)(liServer *srv, liPlugin *p); +typedef void (*liPluginServerStateWorker)(liServer *srv, liPlugin *p, liWorker *wrk); +typedef void (*liPluginServerState)(liServer *srv, liPlugin *p); typedef void (*liPluginHandleCloseCB) (liConnection *con, liPlugin *p); typedef liHandlerResult(*liPluginHandleVRequestCB)(liVRequest *vr, liPlugin *p); @@ -33,8 +33,6 @@ struct liPlugin { size_t opt_base_index, optptr_base_index; - gboolean ready_for_next_state; /**< don't modify this; use li_plugin_ready_for_state() instead */ - liPluginFreeCB free; /**< called before plugin is unloaded */ liPluginHandleVRequestCB handle_request_body; @@ -47,6 +45,10 @@ struct liPlugin { /** called for every plugin after vrequest got reset */ liPluginHandleVRCloseCB handle_vrclose; + liPluginServerStateWorker handle_prepare_worker; /**< called in the worker thread context once before running the workers */ + /* server state machine hooks */ + liPluginServerState handle_prepare, handle_start_listen, handle_stop_listen, handle_start_log, handle_stop_log; + const liPluginOption *options; const liPluginOptionPtr *optionptrs; const liPluginAction *actions; diff --git a/include/lighttpd/server.h b/include/lighttpd/server.h index e1817e6..5d11d7f 100644 --- a/include/lighttpd/server.h +++ b/include/lighttpd/server.h @@ -132,7 +132,6 @@ struct liServer { LI_API liServer* li_server_new(const gchar *module_dir); LI_API void li_server_free(liServer* srv); LI_API gboolean li_server_loop_init(liServer *srv); -LI_API gboolean li_server_worker_init(liServer *srv); LI_API liServerSocket* li_server_listen(liServer *srv, int fd); diff --git a/src/main/plugin.c b/src/main/plugin.c index 0799812..0a29960 100644 --- a/src/main/plugin.c +++ b/src/main/plugin.c @@ -590,21 +590,82 @@ static void li_plugin_free_default_options(liServer *srv, liPlugin *p) { } void li_plugins_prepare_worker(liWorker *wrk) { /* blocking callbacks */ - /* TODO */ + GHashTableIter iter; + liPlugin *p; + gpointer v; + liServer *srv = wrk->srv; + + g_hash_table_iter_init(&iter, srv->plugins); + while (g_hash_table_iter_next(&iter, NULL, &v)) { + p = (liPlugin*) v; + if (p->handle_prepare_worker) { + p->handle_prepare_worker(srv, p, wrk); + } + } } void li_plugins_prepare(liServer* srv) { /* "prepare", async */ - /* TODO */ + GHashTableIter iter; + liPlugin *p; + gpointer v; + + g_hash_table_iter_init(&iter, srv->plugins); + while (g_hash_table_iter_next(&iter, NULL, &v)) { + p = (liPlugin*) v; + if (p->handle_prepare) { + p->handle_prepare(srv, p); + } + } } void li_plugins_start_listen(liServer *srv) { /* "warmup" */ - /* TODO */ + GHashTableIter iter; + liPlugin *p; + gpointer v; + + g_hash_table_iter_init(&iter, srv->plugins); + while (g_hash_table_iter_next(&iter, NULL, &v)) { + p = (liPlugin*) v; + if (p->handle_start_listen) { + p->handle_start_listen(srv, p); + } + } } void li_plugins_stop_listen(liServer *srv) { /* "prepare suspend", async */ - /* TODO */ + GHashTableIter iter; + liPlugin *p; + gpointer v; + + g_hash_table_iter_init(&iter, srv->plugins); + while (g_hash_table_iter_next(&iter, NULL, &v)) { + p = (liPlugin*) v; + if (p->handle_stop_listen) { + p->handle_stop_listen(srv, p); + } + } } void li_plugins_start_log(liServer *srv) { /* "run" */ - /* TODO */ + GHashTableIter iter; + liPlugin *p; + gpointer v; + + g_hash_table_iter_init(&iter, srv->plugins); + while (g_hash_table_iter_next(&iter, NULL, &v)) { + p = (liPlugin*) v; + if (p->handle_start_log) { + p->handle_start_log(srv, p); + } + } } void li_plugins_stop_log(liServer *srv) { /* "suspend now" */ - /* TODO */ + GHashTableIter iter; + liPlugin *p; + gpointer v; + + g_hash_table_iter_init(&iter, srv->plugins); + while (g_hash_table_iter_next(&iter, NULL, &v)) { + p = (liPlugin*) v; + if (p->handle_stop_log) { + p->handle_stop_log(srv, p); + } + } } diff --git a/src/main/server.c b/src/main/server.c index f4824fe..e84601a 100644 --- a/src/main/server.c +++ b/src/main/server.c @@ -280,6 +280,7 @@ void li_server_free(liServer* srv) { static gpointer server_worker_cb(gpointer data) { liWorker *wrk = (liWorker*) data; + li_plugins_prepare_worker(wrk); li_worker_run(wrk); return NULL; } @@ -318,7 +319,7 @@ static void li_server_1sec_timer(struct ev_loop *loop, ev_timer *w, int revents) } } -gboolean li_server_worker_init(liServer *srv) { +static gboolean li_server_worker_init(liServer *srv) { struct ev_loop *loop = srv->loop; guint i; @@ -336,7 +337,6 @@ gboolean li_server_worker_init(liServer *srv) { srv->main_worker = g_array_index(srv->workers, liWorker*, 0) = li_worker_new(srv, loop); srv->main_worker->ndx = 0; for (i = 1; i < srv->worker_count; i++) { - GError *error = NULL; liWorker *wrk; if (NULL == (loop = ev_loop_new(srv->loop_flags))) { li_fatal ("could not create extra libev loops"); @@ -344,13 +344,22 @@ gboolean li_server_worker_init(liServer *srv) { } wrk = g_array_index(srv->workers, liWorker*, i) = li_worker_new(srv, loop); wrk->ndx = i; + } + + return TRUE; +} + +static void li_server_worker_run(liServer *srv) { + guint i; + li_plugins_prepare_worker(srv->main_worker); + + for (i = 1; i < srv->worker_count; i++) { + GError *error = NULL; + liWorker *wrk = g_array_index(srv->workers, liWorker*, i); if (NULL == (wrk->thread = g_thread_create(server_worker_cb, wrk, TRUE, &error))) { g_error ( "g_thread_create failed: %s", error->message ); - return FALSE; } } - - return TRUE; } static void server_connection_limit_hit(liServer *srv) { @@ -760,6 +769,8 @@ void li_server_reached_state(liServer *srv, liServerState state) { case LI_SERVER_SUSPENDED: if (LI_SERVER_SUSPENDING == old_state) { li_plugins_stop_log(srv); + } else if (LI_SERVER_LOADING == old_state) { + li_server_worker_run(srv); } break; case LI_SERVER_WARMUP: