You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tcl.apache.org by mx...@apache.org on 2019/06/24 13:01:26 UTC
[tcl-rivet] 01/01: single thread exit code for mod_rivet 3.2
This is an automated email from the ASF dual-hosted git repository.
mxmanghi pushed a commit to branch single-thread-exit
in repository https://gitbox.apache.org/repos/asf/tcl-rivet.git
commit ca4eb9431b65e16a1e0453dd1e70f19a66e124da
Author: Massimo Manghi <mx...@apache.org>
AuthorDate: Mon Jun 24 15:01:02 2019 +0200
single thread exit code for mod_rivet 3.2
---
src/mod_rivet_ng/apache_config.c | 54 +++++++++++++++++---------------
src/mod_rivet_ng/mod_rivet.c | 2 --
src/mod_rivet_ng/mod_rivet.h | 42 ++++++++++++++-----------
src/mod_rivet_ng/mod_rivet_common.c | 43 ++++++++++++++++++++++---
src/mod_rivet_ng/mod_rivet_common.h | 6 ++--
src/mod_rivet_ng/mod_rivet_generator.c | 18 +++--------
src/mod_rivet_ng/mod_rivet_generator.h | 4 +--
src/mod_rivet_ng/rivetCore.c | 2 +-
src/mod_rivet_ng/rivet_lazy_mpm.c | 14 ++++-----
src/mod_rivet_ng/rivet_prefork_mpm.c | 12 ++++---
src/mod_rivet_ng/rivet_worker_mpm.c | 48 ++++++++++++++--------------
src/mod_rivet_ng/worker_prefork_common.c | 18 +++++------
12 files changed, 146 insertions(+), 117 deletions(-)
diff --git a/src/mod_rivet_ng/apache_config.c b/src/mod_rivet_ng/apache_config.c
index e82472d..da34b38 100644
--- a/src/mod_rivet_ng/apache_config.c
+++ b/src/mod_rivet_ng/apache_config.c
@@ -15,8 +15,6 @@
limitations under the License.
*/
-/* $Id$ */
-
/* Rivet config */
#ifdef HAVE_CONFIG_H
#include <rivet_config.h>
@@ -221,13 +219,14 @@ Rivet_CopyConfig( rivet_server_conf *oldrsc, rivet_server_conf *newrsc )
newrsc->after_every_script = oldrsc->after_every_script;
//newrsc->user_scripts_updated = oldrsc->user_scripts_updated;
//newrsc->rivet_default_error_script = oldrsc->rivet_default_error_script;
- newrsc->default_cache_size = oldrsc->default_cache_size;
- newrsc->upload_max = oldrsc->upload_max;
+ newrsc->default_cache_size = oldrsc->default_cache_size;
+ newrsc->upload_max = oldrsc->upload_max;
newrsc->upload_files_to_var = oldrsc->upload_files_to_var;
newrsc->separate_virtual_interps = oldrsc->separate_virtual_interps;
newrsc->export_rivet_ns = oldrsc->export_rivet_ns;
newrsc->import_rivet_ns = oldrsc->import_rivet_ns;
newrsc->honor_header_only_reqs = oldrsc->honor_header_only_reqs;
+ newrsc->single_thread_exit = oldrsc->single_thread_exit;
newrsc->separate_channels = oldrsc->separate_channels;
newrsc->server_name = oldrsc->server_name;
newrsc->upload_dir = oldrsc->upload_dir;
@@ -237,7 +236,6 @@ Rivet_CopyConfig( rivet_server_conf *oldrsc, rivet_server_conf *newrsc )
newrsc->idx = oldrsc->idx;
newrsc->path = oldrsc->path;
newrsc->mpm_bridge = oldrsc->mpm_bridge;
- //newrsc->user_conf = oldrsc->user_conf;
newrsc->user_scripts_status = oldrsc->user_scripts_status;
}
@@ -409,13 +407,13 @@ Rivet_MergeConfig(apr_pool_t *p, void *basev, void *overridesv)
rsc->separate_virtual_interps = base->separate_virtual_interps;
rsc->honor_header_only_reqs = base->honor_header_only_reqs;
+ rsc->single_thread_exit = base->single_thread_exit;
rsc->separate_channels = base->separate_channels;
rsc->import_rivet_ns = base->import_rivet_ns;
rsc->export_rivet_ns = base->export_rivet_ns;
rsc->mpm_bridge = base->mpm_bridge;
rsc->upload_max = base->upload_max;
rsc->upload_dir = base->upload_dir;
-
RIVET_CONF_SELECT(rsc,base,overrides,upload_dir)
RIVET_CONF_SELECT(rsc,base,overrides,rivet_server_vars)
@@ -449,7 +447,7 @@ Rivet_CreateConfig(apr_pool_t *p, server_rec *s )
rsc->rivet_child_init_script = NULL;
rsc->rivet_child_exit_script = NULL;
rsc->rivet_before_script = NULL;
- //rsc->request_handler = "::Rivet::request_handling";
+ //rsc->request_handler = "::Rivet::request_handling";
rsc->request_handler = NULL;
rsc->rivet_after_script = NULL;
@@ -468,6 +466,7 @@ Rivet_CreateConfig(apr_pool_t *p, server_rec *s )
rsc->export_rivet_ns = RIVET_NAMESPACE_EXPORT;
rsc->import_rivet_ns = RIVET_NAMESPACE_IMPORT;
rsc->honor_header_only_reqs = RIVET_HEAD_REQUESTS;
+ rsc->single_thread_exit = 0;
rsc->separate_channels = RIVET_SEPARATE_CHANNELS;
rsc->upload_dir = RIVET_UPLOAD_DIR;
rsc->server_name = NULL;
@@ -617,6 +616,7 @@ Rivet_DirConf(cmd_parms *cmd,void *vrdc,const char *var,const char *val)
* RivetServerConf SeparateVirtualInterps <yes|no>
* RivetServerConf HonorHeaderOnlyRequests <yes|no> (2008-06-20: mm)
* RivetServerConf MpmBridge <path-to-mpm-bridge>|<bridge-label> (2015-12-14: mm)
+ * RivetServerConf SingleThreadExit <On|Off> (2019-05-23: mm)
*/
const char *
@@ -632,31 +632,33 @@ Rivet_ServerConf(cmd_parms *cmd,void *dummy,const char *var,const char *val)
return "Rivet Error: RivetServerConf requires two arguments";
}
- if ( STREQU ( var, "CacheSize" ) ) {
+ if (STREQU (var,"CacheSize")) {
rsc->default_cache_size = strtol( val, NULL, 10 );
- } else if ( STREQU ( var, "UploadDirectory" ) ) {
+ } else if (STREQU (var,"UploadDirectory")) {
rsc->upload_dir = val;
- } else if ( STREQU ( var, "UploadMaxSize" ) ) {
- rsc->upload_max = strtol( val, NULL, 10 );
- } else if ( STREQU ( var, "UploadFilesToVar" ) ) {
- Tcl_GetBoolean (NULL, val, &rsc->upload_files_to_var);
- } else if ( STREQU ( var, "SeparateVirtualInterps" ) ) {
- Tcl_GetBoolean (NULL, val, &rsc->separate_virtual_interps);
- } else if ( STREQU ( var, "HonorHeaderOnlyRequests" ) ) {
- Tcl_GetBoolean (NULL, val, &rsc->honor_header_only_reqs);
- } else if ( STREQU ( var, "SeparateChannels" ) ) {
- Tcl_GetBoolean (NULL, val, &rsc->separate_channels);
- } else if ( STREQU ( var, "MpmBridge" ) ) {
+ } else if (STREQU (var,"UploadMaxSize")) {
+ rsc->upload_max = strtol(val,NULL,10);
+ } else if (STREQU (var,"UploadFilesToVar")) {
+ Tcl_GetBoolean (NULL,val,&rsc->upload_files_to_var);
+ } else if (STREQU (var,"SeparateVirtualInterps")) {
+ Tcl_GetBoolean (NULL,val,&rsc->separate_virtual_interps);
+ } else if (STREQU (var,"HonorHeaderOnlyRequests")) {
+ Tcl_GetBoolean (NULL,val,&rsc->honor_header_only_reqs);
+ } else if (STREQU (var,"SingleThreadExit")) {
+ Tcl_GetBoolean (NULL,val,&rsc->single_thread_exit);
+ } else if (STREQU (var,"SeparateChannels")) {
+ Tcl_GetBoolean (NULL,val,&rsc->separate_channels);
+ } else if (STREQU (var,"MpmBridge")) {
rsc->mpm_bridge = val;
- } else if ( STREQU (var, "ImportRivetNS")) {
- Tcl_GetBoolean (NULL,val, &rsc->import_rivet_ns);
- } else if ( STREQU (var,"ExportRivetNS")) {
- Tcl_GetBoolean (NULL, val, &rsc->export_rivet_ns);
+ } else if (STREQU (var,"ImportRivetNS")) {
+ Tcl_GetBoolean (NULL,val,&rsc->import_rivet_ns);
+ } else if (STREQU (var,"ExportRivetNS")) {
+ Tcl_GetBoolean (NULL,val,&rsc->export_rivet_ns);
} else {
- string = Rivet_SetScript( cmd->pool, rsc, var, val);
+ string = Rivet_SetScript(cmd->pool,rsc,var,val);
}
- if (string != NULL) apr_table_set( rsc->rivet_server_vars, var, string );
+ if (string != NULL) apr_table_set(rsc->rivet_server_vars, var, string);
return(NULL);
}
diff --git a/src/mod_rivet_ng/mod_rivet.c b/src/mod_rivet_ng/mod_rivet.c
index 6cb94a5..c6ffb60 100644
--- a/src/mod_rivet_ng/mod_rivet.c
+++ b/src/mod_rivet_ng/mod_rivet.c
@@ -19,8 +19,6 @@
under the License.
*/
-/* $Id$ */
-
/* Rivet config */
#ifdef HAVE_CONFIG_H
#include <rivet_config.h>
diff --git a/src/mod_rivet_ng/mod_rivet.h b/src/mod_rivet_ng/mod_rivet.h
index a3633a5..16ffa87 100644
--- a/src/mod_rivet_ng/mod_rivet.h
+++ b/src/mod_rivet_ng/mod_rivet.h
@@ -19,8 +19,6 @@
under the License.
*/
-/* $Id$ */
-
#ifndef __mod_rivet_h__
#define __mod_rivet_h__
@@ -39,13 +37,13 @@
/*
* Petasis 16 Dec 2018: This causes the symbol to be exported also from MPMs...
-
- APLOG_USE_MODULE(rivet);
-
- PLEASE: do not use any of APLOG_USE_MODULE, AP_DECLARE_MODULE,
- AP_MODULE_DECLARE_DATA in this header file!
-
-*/
+ *
+ * APLOG_USE_MODULE(rivet);
+ *
+ * PLEASE: do not use any of APLOG_USE_MODULE, AP_DECLARE_MODULE,
+ * AP_MODULE_DECLARE_DATA in this header file!
+ *
+ */
/* init.tcl file relative to the server root directory */
@@ -95,10 +93,10 @@
/*
* Petasis 10 Aug 2017: This causes the symbol to be exported also from MPMs...
-
- module AP_MODULE_DECLARE_DATA rivet_module;
-
-*/
+ *
+ * module AP_MODULE_DECLARE_DATA rivet_module;
+ *
+ */
typedef struct _rivet_server_conf {
@@ -127,6 +125,9 @@ typedef struct _rivet_server_conf {
int upload_files_to_var;
int separate_virtual_interps;
int honor_header_only_reqs;
+ int single_thread_exit; /* Allow bridges to exit a single thread instead of
+ * forcing a whole process */
+
int separate_channels; /* when true a vhosts get their private channel */
int export_rivet_ns; /* export the ::rivet namespace commands */
int import_rivet_ns; /* import into the global namespace the
@@ -136,10 +137,10 @@ typedef struct _rivet_server_conf {
apr_table_t* rivet_server_vars;
apr_table_t* rivet_dir_vars;
apr_table_t* rivet_user_vars;
- int idx; /* server record index (to be used for the interps db) */
- char* path; /* copy of the path field of a cmd_parms structure:
- * should enable us to tell if a conf record comes from a
- * Directory section */
+ int idx; /* server record index (to be used for the interps db) */
+ char* path; /* copy of the path field of a cmd_parms structure: *
+ * should enable us to tell if a conf record comes from a *
+ * Directory section */
const char* mpm_bridge; /* MPM bridge. if not null the module will try to load the *
* file name in this field. The string should be either a full *
* path to a file name, or a string from which a file name will *
@@ -182,7 +183,7 @@ typedef void (RivetBridge_ThreadInit) (apr_pool_t* pPool,s
typedef int (RivetBridge_Request) (request_rec*,rivet_req_ctype);
typedef apr_status_t (RivetBridge_Finalize) (void*);
typedef rivet_thread_interp* (RivetBridge_Master_Interp) (void);
-typedef int (RivetBridge_Exit_Handler) (int);
+typedef int (RivetBridge_Exit_Handler) (rivet_thread_private*);
typedef rivet_thread_interp* (RivetBridge_Thread_Interp) (rivet_thread_private*,rivet_server_conf *,rivet_thread_interp*);
typedef struct _mpm_bridge_table {
@@ -313,6 +314,11 @@ Tcl_Obj* Rivet_CurrentServerRec (Tcl_Interp* interp, server_rec* s);
Tcl_IncrRefCount(running_script->objscript);\
}
+#define RIVET_SCRIPT_DISPOSE(running_scripts,script_name) \
+ if (running_scripts->script_name != NULL) {\
+ Tcl_DecrRefCount(running_scripts->script_name);\
+ }
+
#define RIVET_MPM_BRIDGE_TABLE bridge_jump_table
#define RIVET_MPM_BRIDGE_FUNCTION(fun) module_globals->bridge_jump_table->fun
diff --git a/src/mod_rivet_ng/mod_rivet_common.c b/src/mod_rivet_ng/mod_rivet_common.c
index 7c3b8a8..f7931d7 100644
--- a/src/mod_rivet_ng/mod_rivet_common.c
+++ b/src/mod_rivet_ng/mod_rivet_common.c
@@ -21,8 +21,6 @@
under the License.
*/
-/* $Id$ */
-
#include <httpd.h>
#include <apr_strings.h>
#include <apr_env.h>
@@ -102,8 +100,7 @@ Rivet_ReadFile (apr_pool_t* pool,char* filename,
return 0;
}
-/*
- *-----------------------------------------------------------------------------
+/*-----------------------------------------------------------------------------
* Rivet_CreateTclInterp --
*
* Arguments:
@@ -184,6 +181,44 @@ running_scripts* Rivet_RunningScripts ( apr_pool_t* pool,
}
/*
+ * -- Rivet_ReleaseRunningScripts
+ *
+ */
+
+void Rivet_ReleaseRunningScripts (running_scripts* scripts)
+{
+ RIVET_SCRIPT_DISPOSE(scripts,rivet_before_script);
+ RIVET_SCRIPT_DISPOSE(scripts,rivet_after_script);
+ RIVET_SCRIPT_DISPOSE(scripts,rivet_error_script);
+ RIVET_SCRIPT_DISPOSE(scripts,rivet_abort_script);
+ RIVET_SCRIPT_DISPOSE(scripts,after_every_script);
+ RIVET_SCRIPT_DISPOSE(scripts,request_processing);
+}
+
+/*
+ * -- Rivet_ReleasePerDirScripts
+ *
+ */
+
+void Rivet_ReleasePerDirScripts(rivet_thread_interp* rivet_interp)
+{
+ apr_hash_t* ht = rivet_interp->per_dir_scripts;
+ apr_hash_index_t* hi;
+ Tcl_Obj* script;
+ apr_pool_t* p = rivet_interp->pool;
+
+ for (hi = apr_hash_first(p,ht); hi; hi = apr_hash_next(hi))
+ {
+ apr_hash_this(hi, NULL, NULL, (void*)(&script));
+ Tcl_DecrRefCount(script);
+ }
+
+ apr_hash_clear(ht);
+
+}
+
+
+/*
*---------------------------------------------------------------------
*
* Rivet_PerInterpInit --
diff --git a/src/mod_rivet_ng/mod_rivet_common.h b/src/mod_rivet_ng/mod_rivet_common.h
index e074ff6..e1a1314 100644
--- a/src/mod_rivet_ng/mod_rivet_common.h
+++ b/src/mod_rivet_ng/mod_rivet_common.h
@@ -19,11 +19,12 @@
under the License.
*/
-#ifndef _MOD_RIVET_COMMON_
-#define _MOD_RIVET_COMMON_
+#ifndef __mod_rivet_common__
+#define __mod_rivet_common__
EXTERN running_scripts* Rivet_RunningScripts (apr_pool_t* pool,running_scripts* scripts,rivet_server_conf* rivet_conf);
EXTERN void Rivet_PerInterpInit(rivet_thread_interp* interp_obj,rivet_thread_private* private, server_rec *s, apr_pool_t *p);
+EXTERN void Rivet_ReleaseRunningScripts (running_scripts* scripts);
EXTERN void Rivet_CreateCache (apr_pool_t *p, rivet_thread_interp* interp_obj);
EXTERN rivet_thread_interp* Rivet_NewVHostInterp(apr_pool_t *pool,server_rec* s);
EXTERN void Rivet_ProcessorCleanup (void *data);
@@ -37,5 +38,6 @@ EXTERN rivet_thread_private* Rivet_ExecutionThreadInit (void);
EXTERN rivet_thread_private* Rivet_SetupTclPanicProc (void);
EXTERN void Rivet_ReleaseRivetChannel (Tcl_Interp* interp, Tcl_Channel* channel);
EXTERN int Rivet_ReadFile (apr_pool_t* pool,char* filename,char** buffer,int* nbytes);
+EXTERN void Rivet_ReleasePerDirScripts(rivet_thread_interp* rivet_interp);
#endif
diff --git a/src/mod_rivet_ng/mod_rivet_generator.c b/src/mod_rivet_ng/mod_rivet_generator.c
index d11d57b..5adae3a 100644
--- a/src/mod_rivet_ng/mod_rivet_generator.c
+++ b/src/mod_rivet_ng/mod_rivet_generator.c
@@ -19,8 +19,6 @@
under the License.
*/
-/* $Id$ */
-
#include <httpd.h>
#include <tcl.h>
#include <apr_strings.h>
@@ -113,7 +111,7 @@ Rivet_ReleaseScripts (running_scripts* scripts)
#define USE_APACHE_RSC
DLLEXPORT int
-Rivet_SendContent(rivet_thread_private *private,request_rec* r)
+Rivet_SendContent(rivet_thread_private *private)
{
int errstatus;
int retval;
@@ -121,14 +119,6 @@ Rivet_SendContent(rivet_thread_private *private,request_rec* r)
rivet_thread_interp* interp_obj;
Tcl_Channel* running_channel;
-#ifdef USE_APACHE_RSC
- //rivet_server_conf *rsc = NULL;
-#else
- //rivet_server_conf *rdc;
-#endif
-
- private->r = r;
-
/* Set the global request req to know what we are dealing with in
* case we have to call the PanicProc. */
@@ -146,7 +136,7 @@ Rivet_SendContent(rivet_thread_private *private,request_rec* r)
interp_obj = RIVET_PEEK_INTERP(private,private->running_conf);
private->running = interp_obj->scripts;
- running_channel = interp_obj->channel;
+ running_channel = interp_obj->channel;
if (private->r->per_dir_config)
{
@@ -345,9 +335,9 @@ sendcleanup:
{
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, private->r,
"process terminating with code %d",private->exit_status);
- RIVET_MPM_BRIDGE_CALL(exit_handler,private->exit_status);
+ RIVET_MPM_BRIDGE_CALL(exit_handler,private);
//Tcl_Exit(private->exit_status);
- exit(private->exit_status);
+ //exit(private->exit_status);
}
/* We now reset the status to prepare the child process for another request */
diff --git a/src/mod_rivet_ng/mod_rivet_generator.h b/src/mod_rivet_ng/mod_rivet_generator.h
index 788acf3..00de5e0 100644
--- a/src/mod_rivet_ng/mod_rivet_generator.h
+++ b/src/mod_rivet_ng/mod_rivet_generator.h
@@ -19,8 +19,6 @@
under the License.
*/
-/* $Id$ */
-
#ifndef __mod_rivet_generator_h__
#define __mod_rivet_generator_h__
@@ -29,6 +27,6 @@
extern int Rivet_CheckType (request_rec* r);
extern int Rivet_ParseExecFile (rivet_thread_private* req, char* filename, int toplevel);
extern int Rivet_ParseExecString (rivet_thread_private* req, Tcl_Obj* inbuf);
-extern int Rivet_SendContent (rivet_thread_private* private,request_rec* r);
+extern int Rivet_SendContent (rivet_thread_private* private);
#endif
diff --git a/src/mod_rivet_ng/rivetCore.c b/src/mod_rivet_ng/rivetCore.c
index 38aef69..e8c3dfd 100644
--- a/src/mod_rivet_ng/rivetCore.c
+++ b/src/mod_rivet_ng/rivetCore.c
@@ -1455,7 +1455,7 @@ TCL_CMD_HEADER( Rivet_ExitCmd )
private->abort_code = Tcl_NewDictObj();
/* The private->abort_code ref count is decremented before
- * request processing terminates*/
+ * request processing terminates */
Tcl_IncrRefCount(private->abort_code);
diff --git a/src/mod_rivet_ng/rivet_lazy_mpm.c b/src/mod_rivet_ng/rivet_lazy_mpm.c
index d406f55..9c7f15b 100644
--- a/src/mod_rivet_ng/rivet_lazy_mpm.c
+++ b/src/mod_rivet_ng/rivet_lazy_mpm.c
@@ -19,8 +19,6 @@
under the License.
*/
-/* $Id$ */
-
#include <httpd.h>
#include <http_request.h>
#include <ap_compat.h>
@@ -219,8 +217,9 @@ static void* APR_THREAD_FUNC request_processor (apr_thread_t *thd, void *data)
private->req_cnt++;
private->ctype = w->ctype;
+ private->r = w->r;
- w->ap_sts = Rivet_SendContent(private,w->r);
+ w->ap_sts = Rivet_SendContent(private);
if (module_globals->mpm->server_shutdown) continue;
@@ -466,11 +465,8 @@ apr_status_t Lazy_MPM_Finalize (void* data)
return APR_SUCCESS;
}
-int Lazy_MPM_ExitHandler(int code)
+int Lazy_MPM_ExitHandler(rivet_thread_private* private)
{
- rivet_thread_private* private;
-
- RIVET_PRIVATE_DATA_NOT_NULL(rivet_thread_key,private)
/* This is not strictly necessary, because this command will
* eventually terminate the whole processes */
@@ -498,10 +494,12 @@ int Lazy_MPM_ExitHandler(int code)
if (module_globals->mpm->exit_command == 0)
{
module_globals->mpm->exit_command = 1;
- module_globals->mpm->exit_command_status = code;
+ module_globals->mpm->exit_command_status = private->exit_status;
}
apr_thread_mutex_unlock(module_globals->mpm->mutex);
+ if (private->running_conf->single_thread_exit) return TCL_OK;
+
/* 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() */
diff --git a/src/mod_rivet_ng/rivet_prefork_mpm.c b/src/mod_rivet_ng/rivet_prefork_mpm.c
index d14ec04..ad252db 100644
--- a/src/mod_rivet_ng/rivet_prefork_mpm.c
+++ b/src/mod_rivet_ng/rivet_prefork_mpm.c
@@ -127,8 +127,9 @@ int Prefork_MPM_Request (request_rec* r,rivet_req_ctype ctype)
private->ctype = ctype;
private->req_cnt++;
+ private->r = r;
- return Rivet_SendContent(private,r);
+ return Rivet_SendContent(private);
}
rivet_thread_interp* MPM_MasterInterp(server_rec* server)
@@ -173,11 +174,14 @@ rivet_thread_interp* MPM_MasterInterp(server_rec* server)
* the thread running the Tcl script will exit
*/
-int Prefork_MPM_ExitHandler(int code)
+int Prefork_MPM_ExitHandler(rivet_thread_private* private)
{
- Tcl_Exit(code);
+ Tcl_Exit(private->exit_status);
- /* it will never get here */
+ /* actually we'll never get here but we return
+ * the Tcl return code anyway to silence the
+ * compilation warning
+ */
return TCL_OK;
}
diff --git a/src/mod_rivet_ng/rivet_worker_mpm.c b/src/mod_rivet_ng/rivet_worker_mpm.c
index 0f94202..729b4b3 100644
--- a/src/mod_rivet_ng/rivet_worker_mpm.c
+++ b/src/mod_rivet_ng/rivet_worker_mpm.c
@@ -19,8 +19,6 @@
under the License.
*/
-/* $Id$*/
-
#include <httpd.h>
#include <math.h>
#include <tcl.h>
@@ -52,7 +50,7 @@
extern DLLIMPORT mod_rivet_globals* module_globals;
extern DLLIMPORT apr_threadkey_t* rivet_thread_key;
-apr_threadkey_t* handler_thread_key;
+// apr_threadkey_t* handler_thread_key;
#ifdef RIVET_NO_HAVE_ROUND
int round(double d) { return (int)(d + 0.5); }
@@ -170,7 +168,7 @@ void Worker_Bridge_Shutdown (void)
}
/*
- * -- request_processor_ng
+ * -- request_processor
*/
static void* APR_THREAD_FUNC request_processor (apr_thread_t *thd, void *data)
@@ -209,13 +207,12 @@ static void* APR_THREAD_FUNC request_processor (apr_thread_t *thd, void *data)
thread_obj = apr_pcalloc(private->pool,sizeof(handler_private));
ap_assert(apr_thread_cond_create(&(thread_obj->cond), private->pool) == APR_SUCCESS);
ap_assert(apr_thread_mutex_create(&(thread_obj->mutex),APR_THREAD_MUTEX_UNNESTED,private->pool)
- == APR_SUCCESS);
+ == APR_SUCCESS);
thread_obj->status = idle;
-
apr_thread_mutex_unlock(module_globals->mpm->job_mutex); /* unlock job initialization stage */
- /* eventually we increment the number of active threads */
+ /* eventually we increment the number of active threads */
apr_atomic_inc32(module_globals->mpm->threads_count);
@@ -255,14 +252,14 @@ static void* APR_THREAD_FUNC request_processor (apr_thread_t *thd, void *data)
private->ctype = thread_obj->ctype;
private->req_cnt++;
+ private->r = thread_obj->r;
- HTTP_REQUESTS_PROC(thread_obj->code = Rivet_SendContent(private,thread_obj->r));
+ HTTP_REQUESTS_PROC(thread_obj->code = Rivet_SendContent(private));
thread_obj->status = done;
- if (private->thread_exit) thread_obj->status = child_exit;
+ // if (private->thread_exit) thread_obj->status = child_exit;
apr_thread_cond_signal(thread_obj->cond);
-
while (thread_obj->status != idle)
{
apr_thread_cond_wait(thread_obj->cond,thread_obj->mutex);
@@ -272,11 +269,11 @@ static void* APR_THREAD_FUNC request_processor (apr_thread_t *thd, void *data)
} while (private->ext->keep_going > 0);
apr_thread_mutex_unlock(thread_obj->mutex);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, module_globals->server, "processor thread orderly exit");
+ ap_log_error(APLOG_MARK,APLOG_DEBUG,0,module_globals->server,"processor thread orderly exit");
- /* We don't clean up the thread resources anymore, if the thread exits the whole process terminates
- * As long as Tcl can't safely delete interpreters this is the way things must be done */
- // Rivet_ProcessorCleanup(private);
+ /* We reestablish the single thread and interpreter cleanup */
+
+ Rivet_ProcessorCleanup(private);
apr_thread_mutex_lock(module_globals->mpm->job_mutex);
*(apr_thread_t **) apr_array_push(module_globals->mpm->exiting) = thd;
@@ -495,7 +492,7 @@ void Worker_MPM_ChildInit (apr_pool_t* pool, server_rec* server)
/* This is the thread key for the framework thread calling the content generation callback */
- ap_assert (apr_threadkey_private_create(&handler_thread_key,NULL,pool) == APR_SUCCESS);
+ // ap_assert (apr_threadkey_private_create(&handler_thread_key,NULL,pool) == APR_SUCCESS);
/* This bridge keeps an array of the ids of threads about to exit. This array is protected by
* the mutex module_globals->job_mutex and signals through module_globals->job_cond
@@ -513,8 +510,9 @@ void Worker_MPM_ChildInit (apr_pool_t* pool, server_rec* server)
exit(1);
}
- /* In order to set up some workload balancing let's
- * query apache for some configuration parameters of the worker MPM
+ /* In order to set up some workload balancing let's
+ * query apache some configuration parameters of
+ * the worker MPM
*/
if (ap_mpm_query(AP_MPMQ_MAX_THREADS,&module_globals->mpm->max_threads) != APR_SUCCESS)
@@ -570,8 +568,8 @@ apr_status_t Worker_RequestPrivateCleanup (void *client_data)
MODNAME ": request thread private data released");
/* we have to invalidate the data pointer */
+ // apr_threadkey_private_set (NULL,handler_thread_key);
- apr_threadkey_private_set (NULL,handler_thread_key);
return APR_SUCCESS;
}
@@ -732,12 +730,8 @@ rivet_thread_interp* MPM_MasterInterp(server_rec* s)
* the thread running the Tcl script will exit
*/
-int Worker_MPM_ExitHandler(int code)
+int Worker_MPM_ExitHandler(rivet_thread_private* private)
{
- rivet_thread_private* private;
-
- RIVET_PRIVATE_DATA_NOT_NULL(rivet_thread_key,private)
-
/* This is not strictly necessary, because this command will
* eventually terminate the whole processes */
@@ -746,11 +740,15 @@ int Worker_MPM_ExitHandler(int code)
private->ext->keep_going = 0;
module_globals->mpm->exit_command = 1;
- module_globals->mpm->exit_command_status = code;
+ 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) return TCL_OK;
/* 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() */
-
+
Worker_MPM_Finalize (private->r->server);
return TCL_OK;
diff --git a/src/mod_rivet_ng/worker_prefork_common.c b/src/mod_rivet_ng/worker_prefork_common.c
index a4a0a56..17b2dac 100644
--- a/src/mod_rivet_ng/worker_prefork_common.c
+++ b/src/mod_rivet_ng/worker_prefork_common.c
@@ -303,13 +303,14 @@ void Rivet_ProcessorCleanup (void *data)
Tcl_DeleteInterp(private->ext->interps[i]->interp);
- /* TODO: in view of restoring the ability of single Tcl interpreter deletion
- * we must also consider to release the per-dir scripts hash table
- * and the Tcl objects storing request handlers (this probably requires
- * request handlers object to be instantiated by calling Tcl_DuplicateObj when
- * needed TODO
- */
-
+ /* Release interpreter scripts */
+
+ Rivet_ReleaseRunningScripts(private->ext->interps[i]->scripts);
+
+ /* Release scripts defined within <Directory...></Directory> conf blocks */
+
+ Rivet_ReleasePerDirScripts(private->ext->interps[i]);
+
/* if separate_virtual_interps == 0 we are running the same interpreter
* instance for each vhost, thus we can jump out of this loop after
* the first cycle as the only real intepreter object we have is stored
@@ -318,7 +319,4 @@ void Rivet_ProcessorCleanup (void *data)
} while ((++i < module_globals->vhosts_count) && rsc->separate_virtual_interps);
- //Tcl_DecrRefCount(private->request_init);
- //Tcl_DecrRefCount(private->request_cleanup);
- apr_pool_destroy(private->pool);
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@tcl.apache.org
For additional commands, e-mail: commits-help@tcl.apache.org