This is an automated email from the ASF dual-hosted git repository. mxmanghi pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/tcl-rivet.git
commit 1bdb883b01fe28226248d7a99ae96c8e4278e72b Author: Massimo Manghi <mxman...@apache.org> AuthorDate: Sun Feb 4 23:39:29 2024 +0100 now calling Rivet_RunChildScripts to execute also rivet_child_exit_script --- ChangeLog | 7 ++ src/mod_rivet_ng/rivetCore.c | 6 +- src/mod_rivet_ng/rivet_lazy_mpm.c | 31 +++++-- src/mod_rivet_ng/rivet_prefork_mpm.c | 4 + src/mod_rivet_ng/rivet_worker_mpm.c | 146 ++++++------------------------- src/mod_rivet_ng/worker_prefork_common.c | 122 +++++++++++++++----------- src/mod_rivet_ng/worker_prefork_common.h | 2 - tests/README | 4 +- 8 files changed, 135 insertions(+), 187 deletions(-) diff --git a/ChangeLog b/ChangeLog index 699e005..9253bbf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2024-02-04 Massimo Manghi <mxman...@apache.org> + * src/mod_rivet_ng/rivet_prefork_mpm.c: + * src/mod_rivet_ng/rivet_worker_mpm.c: + * src/mod_rivet_ng/worker_prefork_common.c: now calling the + new function Rivet_RunChildScripts to execute + both rivet_child_init_script and rivet_child_exit_script + 2024-01-05 Massimo Manghi <mxman...@apache.org> * VERSION: bumped version number as 3.2.4 diff --git a/src/mod_rivet_ng/rivetCore.c b/src/mod_rivet_ng/rivetCore.c index b54c8c1..6e27a7f 100644 --- a/src/mod_rivet_ng/rivetCore.c +++ b/src/mod_rivet_ng/rivetCore.c @@ -1757,8 +1757,8 @@ TCL_CMD_HEADER( Rivet_InspectCmd ) * * log_error priority message * - * priority can be one of "emerg", "alert", "crit", "err", - * "warning", "notice", "info", "debug" + * priority can be one of "emerg","alert","crit","err", + * "warning","notice","info","debug" * * Results: * A message is logged to the Apache error log. @@ -1773,7 +1773,7 @@ TCL_CMD_HEADER(Rivet_LogErrorCmd) server_rec *serverRec; int loglevelindex; - int apLogLevel = 0; + int apLogLevel = 0; static CONST86 char *logLevel[] = { "emerg", diff --git a/src/mod_rivet_ng/rivet_lazy_mpm.c b/src/mod_rivet_ng/rivet_lazy_mpm.c index 9ac53d7..72fcc1a 100644 --- a/src/mod_rivet_ng/rivet_lazy_mpm.c +++ b/src/mod_rivet_ng/rivet_lazy_mpm.c @@ -107,26 +107,41 @@ static void Lazy_RunConfScript (rivet_thread_private* private,lazy_tcl_worker* w case child_global: function = w->conf->rivet_global_init_script; break; case child_init: function = w->conf->rivet_child_init_script; - break; + break; case child_exit: function = w->conf->rivet_child_exit_script; } if (function) { + rivet_interp_globals* globals = NULL; tcl_conf_script = Tcl_NewStringObj(function,-1); Tcl_IncrRefCount(tcl_conf_script); + /* before we run a script we have to store the pointer to the + * running configuration in the thread private data. The design has + * to improve and running a script must have everything sanely + * prepared TODO + */ + + globals = Tcl_GetAssocData(interp,"rivet",NULL); + + /* + * The current server record is stored to enable ::rivet::apache_log_error and + * other commands to log error messages in the virtual host's designated log file + */ + + globals->server = w->server; + if (Tcl_EvalObjEx(interp,tcl_conf_script, 0) != TCL_OK) { char* errmsg = "rivet_lazy_mpm.so: Error in configuration script: %s"; server_rec* root_server = module_globals->server; - ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL,root_server, - errmsg, function); - ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL,root_server, - "errorCode: %s", Tcl_GetVar(interp, "errorCode", 0)); - ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL,root_server, - "errorInfo: %s", Tcl_GetVar(interp, "errorInfo", 0)); + ap_log_error(APLOG_MARK,APLOG_ERR,APR_EGENERAL,root_server,errmsg,function); + ap_log_error(APLOG_MARK,APLOG_ERR,APR_EGENERAL,root_server, + "errorCode: %s",Tcl_GetVar(interp,"errorCode",0)); + ap_log_error(APLOG_MARK,APLOG_ERR,APR_EGENERAL,root_server, + "errorInfo: %s",Tcl_GetVar(interp,"errorInfo",0)); } Tcl_DecrRefCount(tcl_conf_script); @@ -183,7 +198,7 @@ static void* APR_THREAD_FUNC request_processor (apr_thread_t *thd, void *data) Rivet_PerInterpInit(private->ext->interp,private,w->server,private->pool); - /* The child initialization is fired. Beware of the terminologic + /* The child initialization is fired. Beware the terminological * trap: we inherited from fork capable systems the term 'child' * meaning 'child process'. In this case the child init actually * is a worker thread initialization, because in a threaded module diff --git a/src/mod_rivet_ng/rivet_prefork_mpm.c b/src/mod_rivet_ng/rivet_prefork_mpm.c index ca3ba2e..e7bc7bb 100644 --- a/src/mod_rivet_ng/rivet_prefork_mpm.c +++ b/src/mod_rivet_ng/rivet_prefork_mpm.c @@ -37,6 +37,7 @@ extern DLLIMPORT apr_threadkey_t* rivet_thread_key; extern module rivet_module; rivet_thread_private* Rivet_VirtualHostsInterps (rivet_thread_private* private); +void Rivet_RunChildScripts (rivet_thread_private* private,bool init); /* -- PreforkBridge_Finalize */ @@ -195,6 +196,9 @@ rivet_thread_interp* MPM_MasterInterp(server_rec* server) int PreforkBridge_ExitHandler(rivet_thread_private* private) { + + Rivet_RunChildScripts(private,false); + Tcl_Exit(private->exit_status); /* actually we'll never get here but we return diff --git a/src/mod_rivet_ng/rivet_worker_mpm.c b/src/mod_rivet_ng/rivet_worker_mpm.c index 4b7bb51..2d4df1c 100644 --- a/src/mod_rivet_ng/rivet_worker_mpm.c +++ b/src/mod_rivet_ng/rivet_worker_mpm.c @@ -58,6 +58,7 @@ int round(double d) { return (int)(d + 0.5); } #endif /* RIVET_NO_HAVE_ROUND */ rivet_thread_private* Rivet_VirtualHostsInterps (rivet_thread_private* private); +void Rivet_RunChildScripts (rivet_thread_private* private,bool init); typedef struct mpm_bridge_status { apr_thread_t* supervisor; @@ -182,58 +183,6 @@ void WorkerBridge_Shutdown (void) return; } -#if 0 -void WorkerBridge_Shutdown (void) -{ - int waits; - void* v; - handler_private* thread_obj; - apr_status_t rv; - apr_uint32_t threads_to_stop; - - apr_thread_mutex_lock(module_globals->mpm->job_mutex); - - module_globals->mpm->server_shutdown = 1; - - /* We wake up the supervisor who is now supposed to stop - * all the Tcl worker threads - */ - - apr_thread_cond_signal(module_globals->mpm->job_cond); - apr_thread_mutex_unlock(module_globals->mpm->job_mutex); - - waits = 5; - do - { - - rv = apr_queue_trypop(module_globals->mpm->queue,&v); - - /* We wait for possible threads that are taking - * time to serve requests and haven't had a chance to - * see the signal - */ - - if (rv == APR_EAGAIN) - { - waits--; - apr_sleep(200000); - continue; - } - - thread_obj = (handler_private*)v; - apr_thread_mutex_lock(thread_obj->mutex); - thread_obj->status = init; - apr_thread_cond_signal(thread_obj->cond); - apr_thread_mutex_unlock(thread_obj->mutex); - - threads_to_stop = apr_atomic_read32(module_globals->mpm->threads_count); - - } while ((waits > 0) && (threads_to_stop > 0)); - - return; -} -#endif - /* * -- request_processor */ @@ -335,6 +284,8 @@ static void* APR_THREAD_FUNC request_processor (apr_thread_t *thd, void *data) } while (private->ext->keep_going > 0); + Rivet_RunChildScripts(private,false); + apr_thread_mutex_unlock(thread_obj->mutex); ap_log_error(APLOG_MARK,APLOG_DEBUG,0,module_globals->server,"processor thread orderly exit"); @@ -388,37 +339,10 @@ static void start_thread_pool (int nthreads) } } -/* -- supervisor_chores - * - */ - -#if 0 -static void supervisor_housekeeping (void) -{ - int nruns = module_globals->num_load_samples; - double devtn; - double count; - - if (nruns == 60) - { - nruns = 0; - module_globals->average_working_threads = 0; - } - - ++nruns; - count = (int) apr_atomic_read32(module_globals->running_threads_count); - - devtn = ((double)count - module_globals->average_working_threads); - module_globals->average_working_threads += devtn / (double)nruns; - module_globals->num_load_samples = nruns; -} -#endif - - /* -- threaded_bridge_supervisor * - * This function runs within a single thread and to the - * start and stop of Tcl worker thread pool. It could be extended also + * This function runs within a single thread abd manages the + * Tcl worker thread pool. It could be extended also * to provide some basic monitoring data. * * As we don't delete Tcl interpreters anymore because it can lead @@ -728,7 +652,8 @@ apr_status_t WorkerBridge_Finalize (void* data) rv = apr_thread_join (&thread_status,module_globals->mpm->supervisor); if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK,APLOG_ERR,rv,s,MODNAME": Error joining supervisor thread"); + ap_log_error(APLOG_MARK,APLOG_ERR,rv,s, + MODNAME": Error joining worker bridge supervisor thread"); } return OK; @@ -783,16 +708,11 @@ int WorkerBridge_ExitHandler(rivet_thread_private* private) private->ext->keep_going = 0; - //module_globals->mpm->exit_command = 1; - //module_globals->mpm->exit_command_status = private->exit_status; - if (!module_globals->single_thread_exit) { - module_globals->mpm->skip_thread_on_exit = 1; - /* We now tell the supervisor to terminate the Tcl worker thread pool to exit - * and is sequence the whole process to shutdown by calling exit() */ + /* We now tell the supervisor to terminate the Tcl worker thread pool */ WorkerBridge_Finalize(private->r->server); @@ -807,39 +727,25 @@ int WorkerBridge_ExitHandler(rivet_thread_private* private) return TCL_OK; } +/* + * -- WorkerBridge_Interp + * + * Either returns the rivet_thread_interp object that's going + * to run the script or stores in the bridge data the interpreter + * associated to a specific rivet_server_conf record + * + * Arguments: - rivet_thread_private* private: thread private data + * - rivet_server_conf* conf: virtual host configuration + * - rivet_thread_interp* interp: If not NULL stores the interpreter + * in the bridge data. + * Returned value: rivet_thread_interp* + * In any case the function returns + * the rivet_thread_interp + * object associated with the virtual host + * configuration + * + */ -#if 0 -int WorkerBridge_ExitHandler(rivet_thread_private* private) -{ - /* This is not strictly necessary, because this command will - * eventually terminate the whole processes - */ - - /* By setting this flag to 0 we let the thread exit when the - * request processing has completed - */ - - private->ext->keep_going = 0; - - module_globals->mpm->exit_command = 1; - module_globals->mpm->exit_command_status = private->exit_status; - - /* In case single_thread_exit we return preparing this thread to exit */ - - if (!private->running_conf->single_thread_exit) - { - /* We now tell the supervisor to terminate the Tcl worker - * thread pool to exit and is sequence the whole process to - * shutdown by calling exit() - */ - - WorkerBridge_Finalize (private->r->server); - - } - - return TCL_OK; -} -#endif rivet_thread_interp* WorkerBridge_Interp (rivet_thread_private* private, rivet_server_conf* conf, rivet_thread_interp* interp) diff --git a/src/mod_rivet_ng/worker_prefork_common.c b/src/mod_rivet_ng/worker_prefork_common.c index 06ae464..9f7c6b0 100644 --- a/src/mod_rivet_ng/worker_prefork_common.c +++ b/src/mod_rivet_ng/worker_prefork_common.c @@ -70,6 +70,71 @@ Rivet_DuplicateVHostInterp(apr_pool_t* pool, rivet_thread_interp* source_obj) return interp_obj; } +/* -- Rivet_RunChildExitScripts + * + * + */ + +void Rivet_RunChildScripts (rivet_thread_private* private,bool init) +{ + server_rec* vhost_server; + server_rec* root_server; + rivet_server_conf* root_server_conf; + void* parentfunction; /* this is topmost initialization script */ + void* function; + + root_server = module_globals->server; + root_server_conf = RIVET_SERVER_CONF (root_server->module_config); + + parentfunction = (init ? root_server_conf->rivet_child_init_script : root_server_conf->rivet_child_exit_script); + for (vhost_server = root_server; vhost_server != NULL; vhost_server = vhost_server->next) + { + rivet_thread_interp* rivet_interp; + rivet_server_conf* myrsc; + rivet_interp_globals* globals = NULL; + + myrsc = RIVET_SERVER_CONF(vhost_server->module_config); + rivet_interp = RIVET_PEEK_INTERP(private,myrsc); + function = (init ? myrsc->rivet_child_init_script : myrsc->rivet_child_exit_script); + if (function && + (vhost_server == root_server || module_globals->separate_virtual_interps || function != parentfunction)) + { + char* errmsg = MODNAME ": Error in Child init script: %s"; + Tcl_Obj* tcl_script_obj = Tcl_NewStringObj(function,-1); + + Tcl_IncrRefCount(tcl_script_obj); + Tcl_Preserve (rivet_interp->interp); + + /* before we run a script we have to store the pointer to the + * running configuration in the thread private data. The design has + * to improve and running a script must have everything sanely + * prepared TODO + */ + + globals = Tcl_GetAssocData(rivet_interp->interp, "rivet", NULL); + + /* + * The current server record is stored to enable ::rivet::apache_log_error and + * other commands to log error messages in the virtual host's designated log file + */ + + globals->server = vhost_server; + private->running_conf = myrsc; + + if (Tcl_EvalObjEx(rivet_interp->interp,tcl_script_obj,0) != TCL_OK) { + ap_log_error(APLOG_MARK,APLOG_ERR,APR_EGENERAL,vhost_server,errmsg, function); + ap_log_error(APLOG_MARK,APLOG_ERR,APR_EGENERAL,vhost_server, + "errorCode: %s", Tcl_GetVar(rivet_interp->interp,"errorCode",0)); + ap_log_error(APLOG_MARK,APLOG_ERR,APR_EGENERAL,vhost_server, + "errorInfo: %s", Tcl_GetVar(rivet_interp->interp,"errorInfo",0)); + } + Tcl_Release (rivet_interp->interp); + Tcl_DecrRefCount(tcl_script_obj); + + } + } +} + /* -- Rivet_VirtualHostsInterps * * The server_rec chain is walked through and server configurations are read to @@ -96,8 +161,8 @@ rivet_thread_private* Rivet_VirtualHostsInterps (rivet_thread_private* private) rivet_server_conf* root_server_conf; rivet_server_conf* myrsc; rivet_thread_interp* root_interp; - void* parentfunction; /* this is topmost initialization script */ - void* function; + // void* parentfunction; /* this is topmost initialization script */ + // void* function; root_server_conf = RIVET_SERVER_CONF (root_server->module_config); root_interp = MPM_MasterInterp(module_globals->server); @@ -143,7 +208,7 @@ rivet_thread_private* Rivet_VirtualHostsInterps (rivet_thread_private* private) /* then we proceed assigning/creating the interpreters for each virtual host */ - parentfunction = root_server_conf->rivet_child_init_script; + // parentfunction = root_server_conf->rivet_child_init_script; for (vhost_server = root_server; vhost_server != NULL; vhost_server = vhost_server->next) { @@ -208,58 +273,13 @@ rivet_thread_private* Rivet_VirtualHostsInterps (rivet_thread_private* private) apr_thread_mutex_lock(module_globals->pool_mutex); myrsc->server_name = (char*) apr_pstrdup (private->pool,vhost_server->server_hostname); apr_thread_mutex_unlock(module_globals->pool_mutex); - - /* when configured a child init script gets evaluated */ - - function = myrsc->rivet_child_init_script; - if (function && - (vhost_server == root_server || module_globals->separate_virtual_interps || function != parentfunction)) - { - char* errmsg = MODNAME ": Error in Child init script: %s"; - Tcl_Obj* tcl_child_init = Tcl_NewStringObj(function,-1); - rivet_interp_globals* globals = NULL; - - Tcl_IncrRefCount(tcl_child_init); - Tcl_Preserve (rivet_interp->interp); - - /* There is a lot of passing pointers around among various structures. - * We should understand if this is all that necessary. - * Here we assign the server_rec pointer to the interpreter which - * is wrong, because without separate interpreters it doens't make - * any sense. TODO - */ - - /* before we run a script we have to store the pointer to the - * running configuration in the thread private data. The design has - * to improve and running a script must have everything sanely - * prepared TODO - */ - - globals = Tcl_GetAssocData(rivet_interp->interp, "rivet", NULL); - - /* - * The current server record is stored to enable ::rivet::apache_log_error and - * other commands to log error messages in the virtual host's designated log file - */ - - globals->server = vhost_server; - private->running_conf = myrsc; - - if (Tcl_EvalObjEx(rivet_interp->interp,tcl_child_init, 0) != TCL_OK) { - ap_log_error(APLOG_MARK, APLOG_ERR,APR_EGENERAL,vhost_server,errmsg, function); - ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL,vhost_server, - "errorCode: %s", Tcl_GetVar(rivet_interp->interp, "errorCode", 0)); - ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL,vhost_server, - "errorInfo: %s", Tcl_GetVar(rivet_interp->interp, "errorInfo", 0)); - } - Tcl_Release (rivet_interp->interp); - Tcl_DecrRefCount(tcl_child_init); - } } + + /* the child init scripts get evaluated */ + Rivet_RunChildScripts(private,true); return private; } - /* * -- Rivet_ProcessorCleanup * diff --git a/src/mod_rivet_ng/worker_prefork_common.h b/src/mod_rivet_ng/worker_prefork_common.h index 6d3b4b7..e1c2103 100644 --- a/src/mod_rivet_ng/worker_prefork_common.h +++ b/src/mod_rivet_ng/worker_prefork_common.h @@ -19,8 +19,6 @@ under the License. */ -/* $Id$ */ - #ifndef __worker_prefork_common_h__ #define __worker_prefork_common_h__ diff --git a/tests/README b/tests/README index a0d1fc0..0fffd86 100644 --- a/tests/README +++ b/tests/README @@ -1,8 +1,6 @@ Test Suite for Rivet ==================== -$Id$ - These tests are intended to automate the testing of core Rivet features. They are not complete at this point, and work on them would be welcome. @@ -21,7 +19,7 @@ be compiled into Apache for this to work. For example: -./runtest.tcl /usr/sbin/apache +./runtest.tcl /usr/sbin/apache -mpm prefork Where to put tests/which files are which: ---------------------------------------- --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@tcl.apache.org For additional commands, e-mail: commits-h...@tcl.apache.org