This is an automated email from the ASF dual-hosted git repository. mxmanghi pushed a commit to branch quattuor in repository https://gitbox.apache.org/repos/asf/tcl-rivet.git
commit afc9a0338f77ab2252cdb705f591bcf05dd5d626 Author: Massimo Manghi <mxman...@apache.org> AuthorDate: Sat Jun 1 12:14:59 2019 +0200 handling single thread exit --- cvsversion.tcl | 124 ------------------------------- src/mod_rivet_ng/mod_rivet.h | 6 +- src/mod_rivet_ng/mod_rivet_common.c | 27 +++---- src/mod_rivet_ng/mod_rivet_generator.c | 16 +--- src/mod_rivet_ng/rivetInspect.c | 3 + src/mod_rivet_ng/rivet_lazy_mpm.c | 10 ++- src/mod_rivet_ng/rivet_worker_mpm.c | 46 +++++++----- src/mod_rivet_ng/worker_prefork_common.c | 4 +- 8 files changed, 58 insertions(+), 178 deletions(-) diff --git a/cvsversion.tcl b/cvsversion.tcl deleted file mode 100755 index f73196c..0000000 --- a/cvsversion.tcl +++ /dev/null @@ -1,124 +0,0 @@ -#!/bin/sh -# the next line restarts using tclsh \ - exec tclsh "$0" "$@" - -# By David N. Welton <dav...@dedasys.com> -# $Id$ - -# This is to generate new versions based on CVS information. - -set newversionvar 0 - -proc newversion { } { - global newversionvar - puts stderr "New version" - set newversionvar 1 -} - -proc diffentries { {dir .} } { - global newversionvar - - set CVSEntries [file join . CVS Entries] - set OldEntries [file join . .OLDEntries] - - puts stderr "Diffentries for $dir" - set currentdir [pwd] - cd $dir - if { ! [file exists $CVSEntries] } { - puts stderr "You must be in a directory with a path to ./CVS/Entries." - } - - if { ! [file exists $OldEntries] } { - puts stderr "No OLDEntries file. It will be created." - set fl [open $OldEntries w] - close $fl - } - - set entries [open $CVSEntries] - set blob "" - while { [gets $entries ln] != -1 } { - lappend blob $ln - } - close $entries - - set oldentries [open $OldEntries] - set blob2 "" - while { [gets $oldentries ln] != -1 } { - lappend blob2 $ln - } - close $oldentries - - if { $blob != $blob2 } { - newversion - } - foreach ln $blob { - # the regexp below scans for directories in CVS Entries files - if { [regexp {^D/(.*)////$} "$ln" match dir] } { - diffentries $dir - } - } - - file copy -force $CVSEntries $OldEntries - cd $currentdir -} - -proc main {} { - global newversionvar - - diffentries - - if { $newversionvar == 0 } { - puts stderr "No changes, exiting." - } else { - if { [file exists VERSION] } { - set versionfile [open VERSION "r"] - gets $versionfile versionstring - close $versionfile - } else { - set versionstring "0.0.0" - } - - if { ! [regexp {([0-9]+)\.([0-9]+)\.([0-9]+)} $versionstring match major minor point] } { - puts stderr "Problem with versionstring '$versionstring', exiting" - exit 1 - } - - set versionfile [ open VERSION "w" ] - if { [catch { - while { 1 } { - puts -nonewline "Current version: $major.$minor.$point. " - puts -nonewline {Increment [M]ajor, m[I]nor, [P]oint release, or [A]bort? >>> } - flush stdout - gets stdin answer - switch [string tolower $answer] { - m { - incr major - set minor 0 - set point 0 - break - } - i { - incr minor - set point 0 - break - } - p { - incr point - break - } - a { - puts "Aborted" - break - } - } - } - puts $versionfile "$major.$minor.$point" - } err] } { - puts stderr "Problem writing VERSION file: $err" - puts $versionfile "$major.$minor.$point" - } - close $versionfile - puts "Done, version is $major.$minor.$point" - } -} -main \ No newline at end of file diff --git a/src/mod_rivet_ng/mod_rivet.h b/src/mod_rivet_ng/mod_rivet.h index ce4c0f4..58e3d16 100644 --- a/src/mod_rivet_ng/mod_rivet.h +++ b/src/mod_rivet_ng/mod_rivet.h @@ -138,9 +138,9 @@ 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 + 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 * diff --git a/src/mod_rivet_ng/mod_rivet_common.c b/src/mod_rivet_ng/mod_rivet_common.c index 3ed47be..59d3ff4 100644 --- a/src/mod_rivet_ng/mod_rivet_common.c +++ b/src/mod_rivet_ng/mod_rivet_common.c @@ -79,7 +79,7 @@ Rivet_DuplicateVHostInterp(apr_pool_t* pool, rivet_thread_interp* source_obj) /* An intepreter must have its own cache */ if (interp_obj->cache_size) { - RivetCache_Create(pool,interp_obj); + RivetCache_Create(interp_obj); } interp_obj->pool = source_obj->pool; @@ -357,8 +357,7 @@ void Rivet_PerInterpInit(rivet_thread_interp* interp_obj, rivet_thread_interp* Rivet_NewVHostInterp(rivet_thread_private* private,server_rec* server) { - apr_pool_t* pool = private->pool; - rivet_thread_interp* interp_obj = apr_pcalloc(pool,sizeof(rivet_thread_interp)); + rivet_thread_interp* interp_obj = apr_pcalloc(private->pool,sizeof(rivet_thread_interp)); rivet_server_conf* rsc; /* The cache size is global so we take it from here */ @@ -385,25 +384,27 @@ rivet_thread_interp* Rivet_NewVHostInterp(rivet_thread_private* private,server_r interp_obj->cache_free = interp_obj->cache_size; } - /* we now create memory from the cache pool as subpool of the thread private pool */ + /* we now create memory for the cache as subpool of the thread private pool */ - if (apr_pool_create(&interp_obj->pool, pool) != APR_SUCCESS) + if (apr_pool_create(&interp_obj->pool, private->pool) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, server, MODNAME ": could not initialize cache private pool"); return NULL; } - // Initialize cache structures + ap_assert(interp_obj->pool != private->pool); + + /* Initialize cache structures */ if (interp_obj->cache_size) { - RivetCache_Create(pool,interp_obj); + RivetCache_Create(interp_obj); } interp_obj->channel = NULL; interp_obj->flags = 0; - interp_obj->scripts = (running_scripts *) apr_pcalloc(pool,sizeof(running_scripts)); - interp_obj->per_dir_scripts = apr_hash_make(pool); + interp_obj->scripts = (running_scripts *) apr_pcalloc(private->pool,sizeof(running_scripts)); + interp_obj->per_dir_scripts = apr_hash_make(private->pool); return interp_obj; } @@ -507,14 +508,14 @@ Rivet_ReleaseRivetChannel (Tcl_Interp* interp, Tcl_Channel* channel) *----------------------------------------------------------------------------- */ -rivet_thread_private* Rivet_CreatePrivateData (apr_pool_t* pPool,bool create_request_obj) +rivet_thread_private* Rivet_CreatePrivateData (apr_pool_t* tPool,bool create_request_obj) { rivet_thread_private* private; ap_assert (apr_threadkey_private_get ((void **)&private,rivet_thread_key) == APR_SUCCESS); //apr_thread_mutex_lock(module_globals->pool_mutex); - private = apr_pcalloc (pPool,sizeof(*private)); + private = apr_pcalloc (tPool,sizeof(*private)); //apr_thread_mutex_unlock(module_globals->pool_mutex); /* @@ -529,14 +530,14 @@ rivet_thread_private* Rivet_CreatePrivateData (apr_pool_t* pPool,bool create_req } */ - private->pool = pPool; + // ap_assert (apr_pool_create (&private->pool, NULL) == APR_SUCCESS); + private->pool = tPool; private->req_cnt = 0; private->r = NULL; private->page_aborting = 0; private->thread_exit = 0; private->exit_status = 0; private->abort_code = NULL; - //private->channel = NULL; private->req = NULL; if (create_request_obj) diff --git a/src/mod_rivet_ng/mod_rivet_generator.c b/src/mod_rivet_ng/mod_rivet_generator.c index 56d4fc3..9ec8469 100644 --- a/src/mod_rivet_ng/mod_rivet_generator.c +++ b/src/mod_rivet_ng/mod_rivet_generator.c @@ -313,8 +313,6 @@ Rivet_SendContent(rivet_thread_private *private,request_rec* r) /* URL referenced script execution and exception handling */ if (Tcl_EvalObjEx(interp, private->running->request_processing,0) == TCL_ERROR) - //if (Rivet_ParseExecFile (private, private->r->filename, 1) != TCL_OK) - //if (Rivet_ExecuteAndCheck(private,private->request_processing) == TCL_ERROR) { /* we don't report errors coming from abort_page execution */ @@ -323,7 +321,7 @@ Rivet_SendContent(rivet_thread_private *private,request_rec* r) request_rec* r = private->r; ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, r->server, - MODNAME ": Error parsing exec file '%s': %s", + MODNAME ": Error evaluating exec file '%s': %s", r->filename, Tcl_GetVar(interp, "errorInfo", 0)); } } @@ -336,16 +334,6 @@ Rivet_SendContent(rivet_thread_private *private,request_rec* r) private->running_conf->user_scripts_status &= ~(unsigned int)USER_SCRIPTS_UPDATED; } - /* and finally we run the request_cleanup procedure (always set) */ - - //if (Tcl_EvalObjEx(interp, private->request_cleanup, 0) == TCL_ERROR) { - // - // ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, private->r, - // MODNAME ": Error evaluating cleanup request: %s", - // Tcl_GetVar(interp, "errorInfo", 0)); - // - //} - /* We finalize the request processing by printing the headers and flushing the rivet channel internal buffer */ @@ -369,7 +357,7 @@ sendcleanup: if (private->thread_exit) { ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, private->r, - "process terminating with code %d",private->exit_status); + "thread 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/rivetInspect.c b/src/mod_rivet_ng/rivetInspect.c index 5424ea8..7a4c231 100644 --- a/src/mod_rivet_ng/rivetInspect.c +++ b/src/mod_rivet_ng/rivetInspect.c @@ -62,6 +62,7 @@ static const char* confDirectives[] = "RequestHandler", "ExportRivetNS", "ImportRivetNS", + "SingleThreadExit", NULL }; @@ -85,6 +86,7 @@ enum confIndices { request_handler, export_rivet_ns, import_rivet_ns, + single_thread_exit, conf_index_terminator }; @@ -147,6 +149,7 @@ Rivet_ReadConfParameter ( Tcl_Interp* interp, case honor_header_only_requests: int_value = Tcl_NewIntObj(rsc->honor_header_only_reqs); break; case export_rivet_ns: int_value = Tcl_NewIntObj(rsc->export_rivet_ns); break; case import_rivet_ns: int_value = Tcl_NewIntObj(rsc->import_rivet_ns); break; + case single_thread_exit: int_value = Tcl_NewIntObj(rsc->single_thread_exit); break; default: return NULL; } diff --git a/src/mod_rivet_ng/rivet_lazy_mpm.c b/src/mod_rivet_ng/rivet_lazy_mpm.c index a84c32e..44ae7f5 100644 --- a/src/mod_rivet_ng/rivet_lazy_mpm.c +++ b/src/mod_rivet_ng/rivet_lazy_mpm.c @@ -206,6 +206,7 @@ static void* APR_THREAD_FUNC request_processor (apr_thread_t *thd, void *data) idx = w->conf->idx; apr_thread_mutex_lock(w->mutex); + ap_log_error(APLOG_MARK,APLOG_DEBUG,APR_SUCCESS,w->server,"processor thread startup completed"); do { module_globals->mpm->vhosts[idx].idle_threads_cnt++; @@ -237,9 +238,12 @@ static void* APR_THREAD_FUNC request_processor (apr_thread_t *thd, void *data) /* rescheduling itself in the array of idle threads */ - apr_thread_mutex_lock(module_globals->mpm->vhosts[idx].mutex); - *(lazy_tcl_worker **) apr_array_push(module_globals->mpm->vhosts[idx].array) = w; - apr_thread_mutex_unlock(module_globals->mpm->vhosts[idx].mutex); + if (private->ext->keep_going) + { + apr_thread_mutex_lock(module_globals->mpm->vhosts[idx].mutex); + *(lazy_tcl_worker **) apr_array_push(module_globals->mpm->vhosts[idx].array) = w; + apr_thread_mutex_unlock(module_globals->mpm->vhosts[idx].mutex); + } } while (private->ext->keep_going); apr_thread_mutex_unlock(w->mutex); diff --git a/src/mod_rivet_ng/rivet_worker_mpm.c b/src/mod_rivet_ng/rivet_worker_mpm.c index 1f2773e..c588d7d 100644 --- a/src/mod_rivet_ng/rivet_worker_mpm.c +++ b/src/mod_rivet_ng/rivet_worker_mpm.c @@ -203,7 +203,7 @@ static void Worker_CreateInterps (rivet_thread_private* private,rivet_thread_int } -/*-- request_processor_ng +/*-- request_processor * */ @@ -211,10 +211,14 @@ static void* APR_THREAD_FUNC request_processor (apr_thread_t *thd, void *data) { rivet_thread_private* private; handler_private* thread_obj; + apr_pool_t* tPool; apr_thread_mutex_lock(module_globals->mpm->job_mutex); - private = Rivet_CreatePrivateData(apr_thread_pool_get(thd),true); + //tPool = apr_thread_pool_get(thd); + ap_assert (apr_pool_create(&tPool,apr_thread_pool_get(thd)) == APR_SUCCESS); + + private = Rivet_CreatePrivateData(tPool,true); ap_assert(private != NULL); //private->channel = Rivet_CreateRivetChannel(private->pool,rivet_thread_key); @@ -287,7 +291,7 @@ static void* APR_THREAD_FUNC request_processor (apr_thread_t *thd, void *data) continue; } - /* we set the status to request_processing */ + /* we set the status to request_processing */ thread_obj->status = request_processing; @@ -296,15 +300,14 @@ static void* APR_THREAD_FUNC request_processor (apr_thread_t *thd, void *data) apr_atomic_inc32(module_globals->mpm->running_threads_count); /* these assignements are crucial for both calling Rivet_SendContent and - * for telling the channel where stuff must be sent to */ + * for telling the channel where stuff must be sent to + */ private->ctype = thread_obj->ctype; private->req_cnt++; HTTP_REQUESTS_PROC(thread_obj->code = Rivet_SendContent(private,thread_obj->r)); - thread_obj->status = done; - if (private->thread_exit) thread_obj->status = child_exit; apr_thread_cond_signal(thread_obj->cond); @@ -314,30 +317,38 @@ static void* APR_THREAD_FUNC request_processor (apr_thread_t *thd, void *data) } apr_atomic_dec32(module_globals->mpm->running_threads_count); - } while (private->ext->keep_going > 0); + } while (private->ext->keep_going); + thread_obj->status = child_exit; apr_thread_mutex_unlock(thread_obj->mutex); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, module_globals->server, "processor thread orderly exit"); { - rivet_server_conf* rsc = RIVET_SERVER_CONF(module_globals->server->module_config); + rivet_server_conf* rsc = RIVET_SERVER_CONF(module_globals->server->module_config); if (rsc->single_thread_exit) { - Rivet_ProcessorCleanup(private); + //Rivet_ProcessorCleanup(private); } } - apr_thread_mutex_lock(module_globals->mpm->job_mutex); - *(apr_thread_t **) apr_array_push(module_globals->mpm->exiting) = thd; - apr_thread_cond_signal(module_globals->mpm->job_cond); - apr_thread_mutex_unlock(module_globals->mpm->job_mutex); + /* Deleting the condition variable and related mutex */ + + apr_thread_mutex_destroy(thread_obj->mutex); + apr_thread_cond_destroy(thread_obj->cond); /* the counter of active threads has to be decremented */ apr_atomic_dec32(module_globals->mpm->threads_count); - /* this call triggers thread private stuff clean up by calling processor_cleanup */ + /* Notifying the supervisor this thread is about to exit */ + + apr_thread_mutex_lock(module_globals->mpm->job_mutex); + *(apr_thread_t **) apr_array_push(module_globals->mpm->exiting) = thd; + apr_thread_cond_signal(module_globals->mpm->job_cond); + apr_thread_mutex_unlock(module_globals->mpm->job_mutex); + + apr_pool_destroy(tPool); apr_thread_exit(thd,APR_SUCCESS); return NULL; @@ -366,7 +377,7 @@ static void start_thread_pool (int nthreads) if (rv != APR_SUCCESS) { - char errorbuf[RIVET_MSG_BUFFER_SIZE]; + char errorbuf[RIVET_MSG_BUFFER_SIZE]; apr_strerror(rv, errorbuf,RIVET_MSG_BUFFER_SIZE); ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, module_globals->server, @@ -437,8 +448,6 @@ static void* APR_THREAD_FUNC threaded_bridge_supervisor (apr_thread_t *thd, void do { - apr_thread_t* p; - apr_thread_mutex_lock(mpm->job_mutex); while (apr_is_empty_array(mpm->exiting) && !mpm->server_shutdown) { @@ -448,6 +457,8 @@ static void* APR_THREAD_FUNC threaded_bridge_supervisor (apr_thread_t *thd, void while (!apr_is_empty_array(mpm->exiting) && !mpm->server_shutdown) { int i; + apr_thread_t* p; + p = *(apr_thread_t **)apr_array_pop(mpm->exiting); for (i = 0; (i < module_globals->mpm->max_threads) && !mpm->server_shutdown; i++) @@ -816,7 +827,6 @@ int Worker_MPM_ExitHandler(rivet_thread_private* private) * and is sequence the whole process to shutdown by calling exit() */ Worker_MPM_Finalize (private->r->server); - exit(private->exit_status); } diff --git a/src/mod_rivet_ng/worker_prefork_common.c b/src/mod_rivet_ng/worker_prefork_common.c index 9f3eae9..1aff536 100644 --- a/src/mod_rivet_ng/worker_prefork_common.c +++ b/src/mod_rivet_ng/worker_prefork_common.c @@ -196,7 +196,7 @@ void Rivet_ProcessorCleanup (rivet_thread_private* private) if ((i == 0) || rsc->separate_virtual_interps) { - RivetCache_Cleanup(private,private->ext->interps[i]); + RivetCache_Destroy(private,private->ext->interps[i]); Tcl_DeleteInterp(private->ext->interps[i]->interp); Rivet_ReleaseRivetChannel(private->ext->interps[i]->interp,private->ext->interps[i]->channel); } @@ -208,6 +208,4 @@ void Rivet_ProcessorCleanup (rivet_thread_private* private) i++; } - - apr_pool_destroy(private->pool); } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@tcl.apache.org For additional commands, e-mail: commits-h...@tcl.apache.org