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/25 11:28:09 UTC
[tcl-rivet] branch single-thread-exit updated: Single thread exit
implementation for 3.2 with better function task definition
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
The following commit(s) were added to refs/heads/single-thread-exit by this push:
new 856cfd2 Single thread exit implementation for 3.2 with better function task definition
856cfd2 is described below
commit 856cfd298fca965d3da7b9126b3c3827d60903d5
Author: Massimo Manghi <mx...@apache.org>
AuthorDate: Tue Jun 25 13:27:50 2019 +0200
Single thread exit implementation for 3.2 with better function task definition
---
ChangeLog | 3 ++
src/mod_rivet_ng/mod_rivet.c | 8 +--
src/mod_rivet_ng/mod_rivet_generator.c | 5 +-
src/mod_rivet_ng/rivetCore.c | 2 -
src/mod_rivet_ng/rivet_lazy_mpm.c | 28 +++++-----
src/mod_rivet_ng/rivet_prefork_mpm.c | 31 +++++------
src/mod_rivet_ng/rivet_worker_mpm.c | 98 ++++++++++++++++++++--------------
7 files changed, 95 insertions(+), 80 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index d1c8088..7d83e1a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+2019-06-25 Massimo Manghi <mx...@apache.org>
+ * : Single thread exit implementation for mod_rivet 3.2
+
2019-05-24 Massimo Manghi <mx...@apache.org>
* src/mod_rivet_ng/rivetCore.c: Add Tcl_DecrRefCnt after
RivetCache_StoreScript as this function itself calls
diff --git a/src/mod_rivet_ng/mod_rivet.c b/src/mod_rivet_ng/mod_rivet.c
index c6ffb60..d3dbc5c 100644
--- a/src/mod_rivet_ng/mod_rivet.c
+++ b/src/mod_rivet_ng/mod_rivet.c
@@ -65,9 +65,9 @@
#include "mod_rivet_generator.h"
module AP_MODULE_DECLARE_DATA rivet_module;
-extern Tcl_ChannelType RivetChan;
-DLLEXPORT apr_threadkey_t* rivet_thread_key = NULL;
-DLLEXPORT mod_rivet_globals* module_globals = NULL;
+extern Tcl_ChannelType RivetChan;
+DLLEXPORT apr_threadkey_t* rivet_thread_key = NULL;
+DLLEXPORT mod_rivet_globals* module_globals = NULL;
#define ERRORBUF_SZ 256
#define TCL_HANDLER_FILE RIVET_DIR"/default_request_handler.tcl"
@@ -441,7 +441,7 @@ static void Rivet_ChildInit (apr_pool_t *pChild, server_rec *server)
* to each of them
*/
- root_server_conf = RIVET_SERVER_CONF( server->module_config );
+ root_server_conf = RIVET_SERVER_CONF(server->module_config);
idx = 0;
for (s = server; s != NULL; s = s->next)
{
diff --git a/src/mod_rivet_ng/mod_rivet_generator.c b/src/mod_rivet_ng/mod_rivet_generator.c
index 5adae3a..9944d93 100644
--- a/src/mod_rivet_ng/mod_rivet_generator.c
+++ b/src/mod_rivet_ng/mod_rivet_generator.c
@@ -333,9 +333,10 @@ sendcleanup:
if (private->thread_exit)
{
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, private->r,
- "process terminating with code %d",private->exit_status);
+ 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);
+
//Tcl_Exit(private->exit_status);
//exit(private->exit_status);
}
diff --git a/src/mod_rivet_ng/rivetCore.c b/src/mod_rivet_ng/rivetCore.c
index e8c3dfd..35c8fa1 100644
--- a/src/mod_rivet_ng/rivetCore.c
+++ b/src/mod_rivet_ng/rivetCore.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/rivet_lazy_mpm.c b/src/mod_rivet_ng/rivet_lazy_mpm.c
index 9c7f15b..f1e569d 100644
--- a/src/mod_rivet_ng/rivet_lazy_mpm.c
+++ b/src/mod_rivet_ng/rivet_lazy_mpm.c
@@ -276,14 +276,14 @@ static lazy_tcl_worker* create_worker (apr_pool_t* pool,server_rec* server)
}
/*
- * -- Lazy_MPM_ChildInit
+ * -- Lazy_Bridge_ChildInit
*
* child process initialization. This function prepares the process
* data structures for virtual hosts and threads management
*
*/
-void Lazy_MPM_ChildInit (apr_pool_t* pool, server_rec* server)
+void Lazy_Bridge_ChildInit (apr_pool_t* pool, server_rec* server)
{
apr_status_t rv;
server_rec* s;
@@ -338,7 +338,7 @@ void Lazy_MPM_ChildInit (apr_pool_t* pool, server_rec* server)
module_globals->mpm->server_shutdown = 0;
}
-/* -- Lazy_MPM_Request
+/* -- Lazy_Bridge_Request
*
* The lazy bridge HTTP request function. This function
* stores the request_rec pointer into the lazy_tcl_worker
@@ -347,7 +347,7 @@ void Lazy_MPM_ChildInit (apr_pool_t* pool, server_rec* server)
* a new thread is created by calling create_worker
*/
-int Lazy_MPM_Request (request_rec* r,rivet_req_ctype ctype)
+int Lazy_Bridge_Request (request_rec* r,rivet_req_ctype ctype)
{
lazy_tcl_worker* w;
int ap_sts;
@@ -410,11 +410,11 @@ int Lazy_MPM_Request (request_rec* r,rivet_req_ctype ctype)
return ap_sts;
}
-/* -- Lazy_MPM_Interp: lazy bridge accessor to the interpreter database
+/* -- Lazy_Bridge_Interp: lazy bridge accessor to the interpreter database
*
*/
-rivet_thread_interp* Lazy_MPM_Interp (rivet_thread_private* private,
+rivet_thread_interp* Lazy_Bridge_Interp (rivet_thread_private* private,
rivet_server_conf* conf,
rivet_thread_interp* interp)
{
@@ -423,7 +423,7 @@ rivet_thread_interp* Lazy_MPM_Interp (rivet_thread_private* private,
return private->ext->interp;
}
-apr_status_t Lazy_MPM_Finalize (void* data)
+apr_status_t Lazy_Bridge_Finalize (void* data)
{
int vh;
rivet_server_conf* conf = RIVET_SERVER_CONF(((server_rec*) data)->module_config);
@@ -465,7 +465,7 @@ apr_status_t Lazy_MPM_Finalize (void* data)
return APR_SUCCESS;
}
-int Lazy_MPM_ExitHandler(rivet_thread_private* private)
+int Lazy_Bridge_ExitHandler(rivet_thread_private* private)
{
/* This is not strictly necessary, because this command will
@@ -504,16 +504,16 @@ int Lazy_MPM_ExitHandler(rivet_thread_private* private)
* to exit and is sequence the whole process to shutdown
* by calling exit() */
- Lazy_MPM_Finalize (private->r->server);
+ Lazy_Bridge_Finalize (private->r->server);
return TCL_OK;
}
DLLEXPORT
RIVET_MPM_BRIDGE {
NULL,
- Lazy_MPM_ChildInit,
- Lazy_MPM_Request,
- Lazy_MPM_Finalize,
- Lazy_MPM_ExitHandler,
- Lazy_MPM_Interp
+ Lazy_Bridge_ChildInit,
+ Lazy_Bridge_Request,
+ Lazy_Bridge_Finalize,
+ Lazy_Bridge_ExitHandler,
+ Lazy_Bridge_Interp
};
diff --git a/src/mod_rivet_ng/rivet_prefork_mpm.c b/src/mod_rivet_ng/rivet_prefork_mpm.c
index ad252db..8de9adb 100644
--- a/src/mod_rivet_ng/rivet_prefork_mpm.c
+++ b/src/mod_rivet_ng/rivet_prefork_mpm.c
@@ -19,8 +19,6 @@
under the License.
*/
-/* $Id$ */
-
#include <apr_strings.h>
#include "mod_rivet.h"
@@ -38,9 +36,9 @@ extern DLLIMPORT apr_threadkey_t* rivet_thread_key;
rivet_thread_private* Rivet_VirtualHostsInterps (rivet_thread_private* private);
-/* -- Prefork_MPM_Finalize */
+/* -- Prefork_Bridge_Finalize */
-apr_status_t Prefork_MPM_Finalize (void* data)
+apr_status_t Prefork_Bridge_Finalize (void* data)
{
rivet_thread_private* private;
server_rec* s = (server_rec*) data;
@@ -54,13 +52,12 @@ apr_status_t Prefork_MPM_Finalize (void* data)
return OK;
}
-
-/* -- Prefork_MPM_ChildInit: bridge child process initialization
+/* -- Prefork_Bridge_ChildInit: bridge child process initialization
*
*/
-void Prefork_MPM_ChildInit (apr_pool_t* pool, server_rec* server)
+void Prefork_Bridge_ChildInit (apr_pool_t* pool, server_rec* server)
{
rivet_thread_private* private;
@@ -103,7 +100,7 @@ void Prefork_MPM_ChildInit (apr_pool_t* pool, server_rec* server)
}
/*
- * -- Prefork_MPM_Request
+ * -- Prefork_Bridge_Request
*
* The prefork implementation of this function is basically a wrapper of
* Rivet_SendContent. The real job is fetching the thread private data
@@ -117,7 +114,7 @@ void Prefork_MPM_ChildInit (apr_pool_t* pool, server_rec* server)
* HTTP status code (see the Apache HTTP web server documentation)
*/
-int Prefork_MPM_Request (request_rec* r,rivet_req_ctype ctype)
+int Prefork_Bridge_Request (request_rec* r,rivet_req_ctype ctype)
{
rivet_thread_private* private;
@@ -162,7 +159,7 @@ rivet_thread_interp* MPM_MasterInterp(server_rec* server)
}
/*
- * -- Prefork_MPM_ExitHandler
+ * -- Prefork_Bridge_ExitHandler
*
* Just calling Tcl_Exit
*
@@ -174,7 +171,7 @@ rivet_thread_interp* MPM_MasterInterp(server_rec* server)
* the thread running the Tcl script will exit
*/
-int Prefork_MPM_ExitHandler(rivet_thread_private* private)
+int Prefork_Bridge_ExitHandler(rivet_thread_private* private)
{
Tcl_Exit(private->exit_status);
@@ -185,7 +182,7 @@ int Prefork_MPM_ExitHandler(rivet_thread_private* private)
return TCL_OK;
}
-rivet_thread_interp* Prefork_MPM_Interp (rivet_thread_private* private,
+rivet_thread_interp* Prefork_Bridge_Interp (rivet_thread_private* private,
rivet_server_conf* conf,
rivet_thread_interp* interp)
{
@@ -197,10 +194,10 @@ rivet_thread_interp* Prefork_MPM_Interp (rivet_thread_private* private,
DLLEXPORT
RIVET_MPM_BRIDGE {
NULL,
- Prefork_MPM_ChildInit,
- Prefork_MPM_Request,
- Prefork_MPM_Finalize,
- Prefork_MPM_ExitHandler,
- Prefork_MPM_Interp
+ Prefork_Bridge_ChildInit,
+ Prefork_Bridge_Request,
+ Prefork_Bridge_Finalize,
+ Prefork_Bridge_ExitHandler,
+ Prefork_Bridge_Interp
};
diff --git a/src/mod_rivet_ng/rivet_worker_mpm.c b/src/mod_rivet_ng/rivet_worker_mpm.c
index 729b4b3..9fdfc23 100644
--- a/src/mod_rivet_ng/rivet_worker_mpm.c
+++ b/src/mod_rivet_ng/rivet_worker_mpm.c
@@ -136,8 +136,18 @@ void Worker_Bridge_Shutdown (void)
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;
- threads_to_stop = apr_atomic_read32(module_globals->mpm->threads_count);
do
{
@@ -154,6 +164,7 @@ void Worker_Bridge_Shutdown (void)
apr_sleep(200000);
continue;
}
+
thread_obj = (handler_private*)v;
apr_thread_mutex_lock(thread_obj->mutex);
thread_obj->status = init;
@@ -352,7 +363,7 @@ static void supervisor_housekeeping (void)
*
* This function runs within a single thread and to the
* start and stop of Tcl worker thread pool. It could be extended also
- * provide some basic monitoring data.
+ * to provide some basic monitoring data.
*
* As we don't delete Tcl interpreters anymore because it can lead
* to seg faults or delays the supervisor threads doesn't restart
@@ -405,7 +416,8 @@ static void* APR_THREAD_FUNC threaded_bridge_supervisor (apr_thread_t *thd, void
/* terminated thread restart */
rv = create_worker_thread (&((apr_thread_t **)mpm->workers)[i]);
- if (rv != APR_SUCCESS) {
+ if (rv != APR_SUCCESS)
+ {
char errorbuf[RIVET_MSG_BUFFER_SIZE];
/* we shouldn't ever be in the condition of not being able to start a new thread
@@ -424,15 +436,17 @@ static void* APR_THREAD_FUNC threaded_bridge_supervisor (apr_thread_t *thd, void
}
}
apr_thread_mutex_unlock(mpm->job_mutex);
+
} while (!mpm->server_shutdown);
- Worker_Bridge_Shutdown();
- if (module_globals->mpm->exit_command)
- {
+ /*
+ if (module_globals->mpm->exit_command)
+ {
ap_log_error(APLOG_MARK,APLOG_DEBUG,APR_SUCCESS,module_globals->server,"Orderly child process exits.");
exit(module_globals->mpm->exit_command_status);
}
+ */
ap_log_error(APLOG_MARK,APLOG_DEBUG,APR_SUCCESS,module_globals->server,"Worker bridge supervisor shuts down");
apr_thread_exit(thd,APR_SUCCESS);
@@ -440,10 +454,10 @@ static void* APR_THREAD_FUNC threaded_bridge_supervisor (apr_thread_t *thd, void
return NULL;
}
-// int Worker_MPM_ServerInit (apr_pool_t *pPool, apr_pool_t *pLog, apr_pool_t *pTemp, server_rec *s) { return OK; }
+// int Worker_Bridge_ServerInit (apr_pool_t *pPool, apr_pool_t *pLog, apr_pool_t *pTemp, server_rec *s) { return OK; }
/*
- * -- Worker_MPM_ChildInit
+ * -- Worker_Bridge_ChildInit
*
* Child initialization function called by the web server framework.
* For this bridge tasks are
@@ -454,7 +468,7 @@ static void* APR_THREAD_FUNC threaded_bridge_supervisor (apr_thread_t *thd, void
*
*/
-void Worker_MPM_ChildInit (apr_pool_t* pool, server_rec* server)
+void Worker_Bridge_ChildInit (apr_pool_t* pool, server_rec* server)
{
apr_status_t rv;
@@ -468,7 +482,8 @@ void Worker_MPM_ChildInit (apr_pool_t* pool, server_rec* server)
module_globals->mpm = apr_pcalloc(pool,sizeof(mpm_bridge_status));
- /* apr_calloc is supposed to allocate zerod memory, but we still make esplicit the initialization
+ /* apr_calloc is supposed to allocate zeroed memory,
+ * but we still make esplicit the initialization
* of some of its fields
*/
@@ -574,7 +589,7 @@ apr_status_t Worker_RequestPrivateCleanup (void *client_data)
}
/*
- * -- Worker_MPM_Request
+ * -- Worker_Bridge_Request
*
* Content generation callback. Actually this function is not
* generating directly content but instead builds a handler_private
@@ -594,7 +609,7 @@ apr_status_t Worker_RequestPrivateCleanup (void *client_data)
* HTTP status code (see the Apache HTTP web server documentation)
*/
-int Worker_MPM_Request (request_rec* r,rivet_req_ctype ctype)
+int Worker_Bridge_Request (request_rec* r,rivet_req_ctype ctype)
{
void* v;
apr_queue_t* q = module_globals->mpm->queue;
@@ -651,35 +666,27 @@ int Worker_MPM_Request (request_rec* r,rivet_req_ctype ctype)
}
/*
- * -- Worker_MPM_Finalize
+ * -- Worker_Bridge_Finalize
*
*
*/
-apr_status_t Worker_MPM_Finalize (void* data)
+apr_status_t Worker_Bridge_Finalize (void* data)
{
apr_status_t rv;
apr_status_t thread_status;
server_rec* s = (server_rec*) data;
-
- 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);
/* If the Function is called by the memory pool cleanup we wait
- * to join the supervisor, otherwise we if the function was called
- * by Worker_MPM_Exit we skip it because this thread itself must exit
+ * to join the supervisor, otherwise if the function was called
+ * by Worker_Bridge_Exit we skip it because this thread itself must exit
* to allow the supervisor to exit in the shortest possible time
*/
if (!module_globals->mpm->exit_command)
{
+ Worker_Bridge_Shutdown();
+
rv = apr_thread_join (&thread_status,module_globals->mpm->supervisor);
if (rv != APR_SUCCESS)
{
@@ -689,6 +696,8 @@ apr_status_t Worker_MPM_Finalize (void* data)
}
// apr_threadkey_private_delete (handler_thread_key);
+ exit(module_globals->mpm->exit_command_status);
+
return OK;
}
@@ -717,7 +726,7 @@ rivet_thread_interp* MPM_MasterInterp(server_rec* s)
}
/*
- * -- Worker_MPM_ExitHandler
+ * -- Worker_Bridge_ExitHandler
*
* Signals a thread to exit by setting the loop control flag to 0
* and by returning a Tcl error with error code THREAD_EXIT_CODE
@@ -730,12 +739,15 @@ rivet_thread_interp* MPM_MasterInterp(server_rec* s)
* the thread running the Tcl script will exit
*/
-int Worker_MPM_ExitHandler(rivet_thread_private* private)
+int Worker_Bridge_ExitHandler(rivet_thread_private* private)
{
/* This is not strictly necessary, because this command will
- * eventually terminate the whole processes */
+ * eventually terminate the whole processes
+ */
- /* This will force the current thread to exit */
+ /* By setting this flag to 0 we let the thread exit when the
+ * request processing has completed
+ */
private->ext->keep_going = 0;
@@ -744,17 +756,21 @@ int Worker_MPM_ExitHandler(rivet_thread_private* private)
/* 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() */
+ 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()
+ */
- Worker_MPM_Finalize (private->r->server);
+ Worker_Bridge_Finalize (private->r->server);
+ }
+
return TCL_OK;
}
-rivet_thread_interp* Worker_MPM_Interp (rivet_thread_private* private,
+rivet_thread_interp* Worker_Bridge_Interp (rivet_thread_private* private,
rivet_server_conf* conf,
rivet_thread_interp* interp)
{
@@ -766,9 +782,9 @@ rivet_thread_interp* Worker_MPM_Interp (rivet_thread_private* private,
DLLEXPORT
RIVET_MPM_BRIDGE {
NULL,
- Worker_MPM_ChildInit,
- Worker_MPM_Request,
- Worker_MPM_Finalize,
- Worker_MPM_ExitHandler,
- Worker_MPM_Interp
+ Worker_Bridge_ChildInit,
+ Worker_Bridge_Request,
+ Worker_Bridge_Finalize,
+ Worker_Bridge_ExitHandler,
+ Worker_Bridge_Interp
};
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@tcl.apache.org
For additional commands, e-mail: commits-help@tcl.apache.org