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/01 10:15:17 UTC

[tcl-rivet] 05/05: handling single thread exit

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 <mx...@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 <da...@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-unsubscribe@tcl.apache.org
For additional commands, e-mail: commits-help@tcl.apache.org