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 2020/09/29 13:48:33 UTC

[tcl-rivet] 02/03: module configuration directives documentation revision

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 6a90136e24219b74f45977bec95904809371728f
Author: Massimo Manghi <mx...@apache.org>
AuthorDate: Tue Sep 29 15:41:07 2020 +0200

    module configuration directives documentation revision
---
 ChangeLog                                |  11 ++++
 doc/xml/directives.xml                   | 103 ++++++++++++++++++-------------
 src/mod_rivet_ng/apache_config.c         |  32 +++++-----
 src/mod_rivet_ng/apache_config.h         |   3 -
 src/mod_rivet_ng/mod_rivet.c             |  83 +++++++++++++++----------
 src/mod_rivet_ng/mod_rivet.h             |  60 ++++++++++--------
 src/mod_rivet_ng/mod_rivet_common.c      |   5 +-
 src/mod_rivet_ng/rivetInspect.c          |  10 +--
 src/mod_rivet_ng/rivet_lazy_mpm.c        |  31 ++++++++--
 src/mod_rivet_ng/rivet_prefork_mpm.c     |  23 ++++++-
 src/mod_rivet_ng/rivet_worker_mpm.c      |  25 +++++++-
 src/mod_rivet_ng/worker_prefork_common.c |  13 ++--
 12 files changed, 254 insertions(+), 145 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 0cad9b7..a53981b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2020-09-28 Massimo Manghi <mx...@apache.org>
+	* src/mod_rivet_ng/mod_rivet.[c|h]:
+	* src/mod_rivet_ng/rivet_[prefork|worker|lazy]_mpm.c:
+	* src/mod_rivet_ng/worker_prefork_common.c:
+	* src/mod_rivet_ng/mod_rivet_commit.c:
+	* src/mod_rivet_ng/apache_config.[c|h]: moving real global setting out
+	of the server configuration record into the module_globals structure,
+	because their global in the first place
+	* doc/xml/directives.xml: extended revision of the directive
+	scope documentation
+
 2020-09-27 Massimo Manghi <mx...@apache.org>
 	* rivet/packages/formbroker/formbroker.tcl: add method form_exists to check for registration
 	of a form
diff --git a/doc/xml/directives.xml b/doc/xml/directives.xml
index 38113fc..9f707aa 100644
--- a/doc/xml/directives.xml
+++ b/doc/xml/directives.xml
@@ -61,31 +61,35 @@
 					any special request handler should explicitly read this script from the configuration
 					using ::rivet::inspect and evaluate it (see <xref linkend="request">request processing</xref>)</td>
 				</tr>
-				<tr><td>AfterScript</td><td>X</td><td>X</td><td>X</td><td>X</td><td>Special request handler developers
-				should read this script from the configuration calling ::rivet::inspect and evaluate it</td></tr>
+				<tr><td>AfterScript</td><td>X</td><td>X</td><td>X</td><td>X</td><td>Special request handler scripts
+				should read it from the configuration calling ::rivet::inspect and evaluate it</td></tr>
 				<tr><td>AfterEveryScript</td><td>X</td><td>X</td><td>X</td><td>X</td><td>See notes for the AfterScript directive</td></tr>
 				<tr><td>BeforeScript</td><td>X</td><td>X</td><td>X</td><td>X</td>
 					 <td>See notes for the AfterScript directive</td></tr>
-				<tr><td>CacheSize</td><td></td><td></td><td>X</td><td></td><td></td></tr>
+				<tr><td>CacheSize</td><td></td><td></td><td>X</td><td>X</td><td></td></tr>
 				<tr><td>ChildExitScript</td><td></td><td></td><td>X</td><td>X</td><td></td></tr>
 				<tr><td>ChildInitScript</td><td></td><td></td><td>X</td><td>X</td><td></td></tr>
 				<tr><td>ErrorScript</td><td>X</td><td>X</td><td>X</td><td>X</td>
-					<td>Rivet provides a default error handler. In case you are developing your own request
-					handling procedure you need to call that handler yourself or develop a new.
-					See notes for the AbortScript and AfterScript directives</td></tr>
-				<tr><td>ExportRivetNS</td><td></td><td></td><td>X</td><td></td><td></td></tr>
+					<td>Rivet provides a default error handler. In case you are writing your own request
+					handling procedure you need to call this error handler yourself or develop your
+					application specific error handler to be integrated into the RequestHandler script.
+					See also the notes for the AbortScript and AfterScript directives</td></tr>
+				<tr><td>ExportRivetNS</td><td></td><td></td><td>X</td><td>X</td><td>It can be set in a virtual host
+				configuration if SeparateVirtualInterps is On, otherwise this directive can be safely used at the global level only</td></tr>
 				<tr><td>GlobalInitScript</td><td></td><td></td><td>X</td><td></td>
 				    <td>effective only when SeparateVirtualInterps is Off (default)</td></tr>
-				<tr><td>ImportRivetNS</td><td></td><td></td><td>X</td><td></td><td>global setting</td></tr>
-				<tr><td>HonorHeaderOnlyRequests</td><td></td><td></td><td>X</td><td></td><td>global setting</td></tr>
-				<tr><td>MpmBridge</td><td></td><td></td><td>X</td><td></td><td>global setting</td></tr>
+				<tr><td>ImportRivetNS</td><td></td><td></td><td>X</td><td>X</td><td>It can be set in a virtual host
+				configuration if SeparateVirtualInterps is On, otherwise this directive can be safely used at the global level only</td></tr>
+				<tr><td>HonorHeaderOnlyRequests</td><td></td><td></td><td>X</td><td>X</td><td></td></tr>
+				<tr><td>MpmBridge</td><td></td><td></td><td>X</td><td></td><td>global only</td></tr>
 				<tr><td>RequestHandler</td><td></td><td></td><td>X</td><td>X</td><td></td></tr>
-				<tr><td>SeparateChannels</td><td></td><td></td><td>X</td><td></td><td>global setting</td></tr> 
-				<tr><td>SeparateVirtualInterps</td><td></td><td></td><td>X</td><td></td><td>global setting</td></tr> 
-				<tr><td>ServerInitScript</td><td></td><td></td><td>X</td><td></td><td></td></tr>
-				<tr><td>SingleThreadExit</td><td></td><td></td><td>X</td><td></td><td>global setting</td></tr>
-				<tr><td>UploadDirectory</td><td></td><td>X</td><td>X</td><td>X</td><td></td></tr> 
-				<tr><td>UploadFilesToVar</td><td></td><td></td><td>X</td><td></td><td></td></tr> 
+				<tr><td>SeparateChannels</td><td></td><td></td><td>X</td><td></td><td>global only (DEPRECATED: will be
+				replaced in future versions of Rivet)</td></tr> 
+				<tr><td>SeparateVirtualInterps</td><td></td><td></td><td>X</td><td></td><td>global only</td></tr> 
+				<tr><td>ServerInitScript</td><td></td><td></td><td>X</td><td></td><td>global only</td></tr>
+				<tr><td>SingleThreadExit</td><td></td><td></td><td>X</td><td></td><td>global only</td></tr>
+				<tr><td>UploadDirectory</td><td>X</td><td>X</td><td>X</td><td>X</td><td></td></tr> 
+				<tr><td>UploadFilesToVar</td><td></td><td></td><td>X</td><td>X</td><td></td></tr> 
 				<tr><td>UploadMaxSize</td><td></td><td></td><td>X</td><td>X</td><td></td></tr>
 			</tbody>
 		</table>
@@ -292,8 +296,8 @@
 	    		<listitem>
 					<para>
 						Rivet commands are created within the ::rivet namespace. Setting
-						this option you tell mod_rivet to place the whole command set on
-						the export list of namespace, enabling your scripts to import
+						this option mod_rivet places the whole command set on
+						the export list of the ::rivet namespace, enabling your scripts to import
 						them in a different namespace.
 					</para>
 					<para>This option is, by nature, only available at the global level</para>
@@ -318,7 +322,7 @@
 					  response. If the real header has to be examined (e.g. 
 					  for debugging) you can turn this options on. 
 					</para>
-					<para>This option is, by nature, only available at the global level</para>
+					<para>This option is only available at the global level</para>
 	      	</listitem>
 	    	</varlistentry>
 
@@ -335,17 +339,14 @@
 	    		<listitem>
 					<para>
 						Rivet commands are created within the ::rivet namespace. Setting
-						this option you tell mod_rivet to place the whole command set on
-						the export list of namespace (implicitly forcing also ExportRivetNS)
-						and then importing the commands on the namespace export list into the 
-						global namespace
+						this option mod_rivet is told to place the whole command set on
+						the export list of the ::rivet namespace (implicitly forcing also ExportRivetNS)
+						and then importing the commands into the global namespace
 					</para>
-					
 					<note>
 						This option is provided only for compatibility with existing code that assumes
-						mod_rivet commands to reside in the global namespace. It's utterly discouraged to
-						use it and it could be removed in future versions of Rivet
-						This option is, by nature, only available at the global level
+						mod_rivet commands to reside in the global namespace it could be removed in
+						future versions of Rivet. This option is only available at the global level
 					</note>
 	      	</listitem>
 	    	</varlistentry>
@@ -360,17 +361,18 @@
 	      	<listitem>
 					<para>
 						This global only option tells mod_rivet which MPM bridge has
-						to be loaded. The string argument is interpreted
-						first as a name of an MPM bridge and it's interpolated in the
-						string
+						to be loaded. The module attempt to interpolate the argument value
 						<programlisting>bridge = apr_pstrcat(pool,RIVET_DIR,"/mpm/rivet_",rsc->mpm_bridge,"_mpm.so",NULL);</programlisting>
 						Where RIVET_DIR is the location of the rivet libraries whose definition
-						is controlled by the configuration argument <term>--with-rivet-target-dir=DIR</term>.
+						is controlled by the configure switch <command>--with-rivet-target-dir=DIR</command>.
 						For example 
 						<programlisting>RivetServerConf MpmBridge lazy</programlisting> will cause the
-						rivet_lazy_mpm.so library module to be loaded. If such library does not exists
-						mod_rivet tries to check if such definition is the fully qualified path to 
-						such MPM bridge. If this fails the module causes the web server to stop with an error.
+						rivet_lazy_mpm.so library module to be loaded.
+					</para>
+					<para>
+						If such library does not exists mod_rivet tries to check if such definition is actually
+						the fully qualified path to such MPM bridge. If this fails the module causes the web server to stop
+						with an error.
 					</para>
 				</listitem>
 	    	</varlistentry>
@@ -507,16 +509,29 @@
    			</term>
    			<listitem>
 		   		<para>
-		   			Rivet shadows the Tcl <command>exit</command> command with the
-		   			<command>::rivet::exit</command> in order to
-		   			prevent abrupt interruption of execution of a child process when
-		   			multiple thread are running. By default the worker bridge notifies
-		   			all the threads running Tcl interpreters to exit before calling Tcl_Exit.
-		   			If this option is set a single thread terminates executing any ChildExitScript 
-		   			and eventually it's replaced accordingly to
-		   			the thread management policy implemented by the bridge. 
-		   			With the prefork bridge this options reproduces the ordinary
-		   			<command>exit</command> command behavior.
+						The Tcl <command>exit</command> command has a simple implementation that
+						eventually calls Tcl_Exit (which in turn calls stdlib's exit) that forces
+						the immediate deletion of all threads in a process. This behavior would be
+		   			unacceptable with the worker MPM and worker bridge which are fundamentally
+		   			threaded. 
+		   			Therefore Rivet shadows the Tcl <command>exit</command> command with
+		   			<command>::rivet::exit</command> which calls a designated function in
+		   			the running bridge. The prefork bridge simply prepares the child process
+		   			to terminate, whereas the worker bridge is behavior controlled by this option.
+		   			<orderedlist>
+		   				<listitem>If SingleThreadExit is set (default) each thread behaves
+		   				individually and terminates after running the ChildExitScript and deleting 
+		   				its Tcl interpreters</listitem>
+		   				<listitem>If SingleThreadExit is <command>No</command> the worker bridge notifies all threads
+		   				to exit and then calls Tcl_Exit</listitem>
+		   			</orderedlist>
+		   			The latter option might be useful in cases where an application is using
+		   			an improperly developed Tcl extension which might cause a child process to crash when
+		   			calling Tcl_DeleteInterp.
+					</para>
+					<para>
+						The default is <command>No</command> for the prefork bridge (loaded by default if the server
+						runs the prefork MPM) and <command>true</command> for the worker and lazy bridges
 		   		</para>
    			</listitem>
 			</varlistentry>
diff --git a/src/mod_rivet_ng/apache_config.c b/src/mod_rivet_ng/apache_config.c
index cb8de23..29331a8 100644
--- a/src/mod_rivet_ng/apache_config.c
+++ b/src/mod_rivet_ng/apache_config.c
@@ -222,12 +222,12 @@ Rivet_CopyConfig( rivet_server_conf *oldrsc, rivet_server_conf *newrsc )
     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->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->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;
     newrsc->rivet_server_vars = oldrsc->rivet_server_vars;
@@ -235,7 +235,7 @@ Rivet_CopyConfig( rivet_server_conf *oldrsc, rivet_server_conf *newrsc )
     newrsc->rivet_user_vars = oldrsc->rivet_user_vars;
     newrsc->idx = oldrsc->idx;
     newrsc->path = oldrsc->path;
-    newrsc->mpm_bridge = oldrsc->mpm_bridge;
+    //newrsc->mpm_bridge = oldrsc->mpm_bridge;
     newrsc->user_scripts_status = oldrsc->user_scripts_status;
 }
 
@@ -405,14 +405,14 @@ Rivet_MergeConfig(apr_pool_t *p, void *basev, void *overridesv)
     RIVET_CONF_SELECT(rsc,base,overrides,after_every_script)
     RIVET_CONF_SELECT(rsc,base,overrides,default_cache_size);
 
-    rsc->separate_virtual_interps = base->separate_virtual_interps;
+    //rsc->separate_virtual_interps = base->separate_virtual_interps;
     rsc->honor_header_only_reqs = base->honor_header_only_reqs;
     rsc->upload_files_to_var = base->upload_files_to_var;
-    rsc->single_thread_exit = base->single_thread_exit;
-    rsc->separate_channels = base->separate_channels;
+    //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->mpm_bridge = base->mpm_bridge;
     rsc->upload_max = base->upload_max;
     rsc->upload_dir = base->upload_dir;
 
@@ -463,15 +463,15 @@ Rivet_CreateConfig(apr_pool_t *p, server_rec *s )
     rsc->default_cache_size         = -1;
     rsc->upload_max                 = RIVET_MAX_POST;
     rsc->upload_files_to_var        = RIVET_UPLOAD_FILES_TO_VAR;
-    rsc->separate_virtual_interps   = RIVET_SEPARATE_VIRTUAL_INTERPS;
+    //rsc->separate_virtual_interps = RIVET_SEPARATE_VIRTUAL_INTERPS;
     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->single_thread_exit         = 0;
+    //rsc->separate_channels          = RIVET_SEPARATE_CHANNELS;
     rsc->upload_dir                 = RIVET_UPLOAD_DIR;
     rsc->server_name                = NULL;
-    rsc->mpm_bridge                 = NULL;
+    //rsc->mpm_bridge                 = NULL;
 
     rsc->rivet_server_vars          = (apr_table_t *) apr_table_make ( p, 4 );
     rsc->rivet_dir_vars             = (apr_table_t *) apr_table_make ( p, 4 );
@@ -642,15 +642,15 @@ Rivet_ServerConf(cmd_parms *cmd,void *dummy,const char *var,const char *val)
     } 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);
+        Tcl_GetBoolean (NULL,val,&module_globals->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);
+        Tcl_GetBoolean (NULL,val,&module_globals->single_thread_exit);
     } else if (STREQU (var,"SeparateChannels")) {
-        Tcl_GetBoolean (NULL,val,&rsc->separate_channels);
+        Tcl_GetBoolean (NULL,val,&module_globals->separate_channels);
     } else if (STREQU (var,"MpmBridge")) {
-        rsc->mpm_bridge = val;
+        module_globals->mpm_bridge = val;
     } else if (STREQU (var,"ImportRivetNS")) {
         Tcl_GetBoolean (NULL,val,&rsc->import_rivet_ns);
     } else if (STREQU (var,"ExportRivetNS")) {
diff --git a/src/mod_rivet_ng/apache_config.h b/src/mod_rivet_ng/apache_config.h
index 0adbab9..44676a5 100644
--- a/src/mod_rivet_ng/apache_config.h
+++ b/src/mod_rivet_ng/apache_config.h
@@ -19,9 +19,6 @@
     under the License.
  */
 
-/* $Id$ */
-
-
 #ifndef __apache_config_h__
 #define __apache_config_h__
 
diff --git a/src/mod_rivet_ng/mod_rivet.c b/src/mod_rivet_ng/mod_rivet.c
index 91550eb..a4481f3 100644
--- a/src/mod_rivet_ng/mod_rivet.c
+++ b/src/mod_rivet_ng/mod_rivet.c
@@ -79,16 +79,16 @@ DLLEXPORT mod_rivet_globals*  module_globals      = NULL;
  */
 
 static char*
-Rivet_SeekMPMBridge (apr_pool_t* pool,server_rec* server)
+Rivet_SeekMPMBridge (apr_pool_t* pool)
 {
     char*   mpm_prefork_bridge = "rivet_prefork_mpm.so";
     char*   mpm_worker_bridge  = "rivet_worker_mpm.so";
     char*   mpm_bridge_path;
     int     ap_mpm_result;
-    rivet_server_conf* rsc = RIVET_SERVER_CONF( server->module_config );
+    //rivet_server_conf* rsc = RIVET_SERVER_CONF( server->module_config );
 
     /* With the env variable RIVET_MPM_BRIDGE we have the chance to tell mod_rivet 
-       what bridge custom implementation we want to be loaded */
+       what bridge custom implementation we want be loaded */
 
     if (apr_env_get (&mpm_bridge_path,"RIVET_MPM_BRIDGE",pool) == APR_SUCCESS)
     {
@@ -97,24 +97,24 @@ Rivet_SeekMPMBridge (apr_pool_t* pool,server_rec* server)
 
     /* we now look into the configuration record */
 
-    if (rsc->mpm_bridge != NULL)
+    if (module_globals->mpm_bridge != NULL)
     {
         apr_finfo_t finfo;
         char*       proposed_bridge;
 
-        proposed_bridge = apr_pstrcat(pool,RIVET_MPM_BRIDGE_COMPOSE(rsc->mpm_bridge),NULL);
+        proposed_bridge = apr_pstrcat(pool,RIVET_MPM_BRIDGE_COMPOSE(module_globals->mpm_bridge),NULL);
         if (apr_stat(&finfo,proposed_bridge,APR_FINFO_MIN,pool) == APR_SUCCESS)
         {
             mpm_bridge_path = proposed_bridge;
         } 
-        else if (apr_stat(&finfo,rsc->mpm_bridge,APR_FINFO_MIN,pool) == APR_SUCCESS)
+        else if (apr_stat(&finfo,module_globals->mpm_bridge,APR_FINFO_MIN,pool) == APR_SUCCESS)
         {
-            mpm_bridge_path = apr_pstrdup(pool,rsc->mpm_bridge);
+            mpm_bridge_path = apr_pstrdup(pool,module_globals->mpm_bridge);
         }
         else
         {   
-            ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, server, 
-                         MODNAME ": MPM bridge %s not found", rsc->mpm_bridge); 
+            ap_log_perror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, pool, 
+                         MODNAME ": MPM bridge %s not found", module_globals->mpm_bridge); 
             exit(1);   
         }
 
@@ -154,42 +154,38 @@ Rivet_SeekMPMBridge (apr_pool_t* pool,server_rec* server)
 /* 
  * -- Rivet_CreateModuleGlobals
  *
- * module globals (mod_rivet_globals) allocation and initialization
+ * module globals (mod_rivet_globals) allocation and initialization.
+ * As of 3.2 the procedure fills the structure fields that can be set
+ * during the pre_config stage of the server initialization
  * 
  */
 
 static mod_rivet_globals* 
-Rivet_CreateModuleGlobals (apr_pool_t* pool, server_rec* server)
+Rivet_CreateModuleGlobals (apr_pool_t* pool)
 {
     mod_rivet_globals*  mod_rivet_g;
    
-    mod_rivet_g = apr_palloc(pool,sizeof(mod_rivet_globals));
+    mod_rivet_g = apr_pcalloc(pool,sizeof(mod_rivet_globals));
+    mod_rivet_g->single_thread_exit       = SINGLE_THREAD_EXIT_UNDEF;
+    mod_rivet_g->separate_virtual_interps = RIVET_SEPARATE_VIRTUAL_INTERPS;
+    mod_rivet_g->separate_channels        = RIVET_SEPARATE_CHANNELS;
     if (apr_pool_create(&mod_rivet_g->pool, NULL) != APR_SUCCESS) 
     {
-        ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, server, 
-                     MODNAME ": could not initialize rivet module global pool");
+        ap_log_perror(APLOG_MARK,APLOG_ERR,APR_EGENERAL,pool,
+                      MODNAME ": could not initialize rivet module global pool");
         exit(1);
     }
 
-    mod_rivet_g->rivet_mpm_bridge = Rivet_SeekMPMBridge(pool,server);
-
     /* read the default request handler code */
 
     if (Rivet_ReadFile(pool,TCL_HANDLER_FILE,
                             &mod_rivet_g->default_handler,
                             &mod_rivet_g->default_handler_size) > 0)
     {
-        ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, server, 
+        ap_log_perror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, pool, 
                      MODNAME ": could not read rivet default handler");
         exit(1);
     }
-    
-    /* We cannot assume we are running in an OS with a fork system call
-     * therefore we have to check module_globals in order to establish if the
-     * structure has to be allocated
-     */
-    
-    mod_rivet_g->server = server;
 
     return mod_rivet_g;
 }
@@ -252,11 +248,11 @@ Rivet_RunServerInit (apr_pool_t *pPool, apr_pool_t *pLog, apr_pool_t *pTemp, ser
 	apr_env_get(&parent_pid_var,"AP_PARENT_PID",pTemp);
 	if (parent_pid_var != NULL)
 	{
-		ap_log_error(APLOG_MARK,APLOG_INFO,0,s,
+		ap_log_perror(APLOG_MARK,APLOG_INFO,0,pPool,
 					"AP_PARENT_PID found: not running the Tcl server script in winnt MPM child process");
 		return OK;
 	} else {
-		ap_log_error(APLOG_MARK,APLOG_INFO,0,s,
+		ap_log_perror(APLOG_MARK,APLOG_INFO,0,pPool,
 				 "AP_PARENT_PID undefined, we proceed with server initialization");
 	}
 	
@@ -280,7 +276,7 @@ Rivet_RunServerInit (apr_pool_t *pPool, apr_pool_t *pLog, apr_pool_t *pTemp, ser
                          rsc->rivet_server_init_script,
                          Tcl_GetVar(interp, "errorInfo", 0));
         } else {
-            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, 
+            ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_EGENERAL, s,
                          MODNAME ": ServerInitScript '%s' successful", 
                          rsc->rivet_server_init_script);
         }
@@ -331,13 +327,18 @@ Rivet_ServerInit (apr_pool_t *pPool, apr_pool_t *pLog, apr_pool_t *pTemp, server
                      "first post_config run: not initializing Tcl stuff");
 
         return OK; /* This would be the first time through */
-	}	
+	}
 	
     /* Everything revolves around this structure: module_globals */
 
     /* the module global structure is allocated and the MPM bridge name established */
 
-    module_globals = Rivet_CreateModuleGlobals (pPool,server);
+    // module_globals = Rivet_CreateModuleGlobals (pPool,server);
+
+    /* We can proceed initializing the globals with information stored in the module configuration */
+
+    module_globals->rivet_mpm_bridge = Rivet_SeekMPMBridge(pPool);
+    module_globals->server           = server;
 
     /* The bridge is loaded and the jump table sought */
 
@@ -346,7 +347,7 @@ Rivet_ServerInit (apr_pool_t *pPool, apr_pool_t *pLog, apr_pool_t *pTemp, server
         apr_status_t            rv;
         apr_dso_handle_sym_t    func = NULL;
 
-        ap_log_error(APLOG_MARK,APLOG_DEBUG,0,server,
+        ap_log_perror(APLOG_MARK,APLOG_DEBUG,APR_EGENERAL,pTemp,
                      "MPM bridge loaded: %s",module_globals->rivet_mpm_bridge);
 
         rv = apr_dso_sym(&func,dso_handle,"bridge_jump_table");
@@ -413,8 +414,8 @@ static void Rivet_ChildInit (apr_pool_t *pChild, server_rec *server)
 
     ap_assert (apr_threadkey_private_create (&rivet_thread_key, NULL, pChild) == APR_SUCCESS);
 
-    /* This code is run once per child process. In a threaded Tcl builds the forking 
-     * of a child process most likely has not preserved the thread where the Tcl 
+    /* This code is run once per child process. The forking 
+     * of a child process doesn't preserve the thread where the Tcl 
      * notifier runs. The Notifier should have been restarted by one the 
      * pthread_atfork callbacks (setup in Tcl >= 8.5.14 and Tcl >= 8.6.1). In
      * case pthread_atfork is not supported we unconditionally call Tcl_InitNotifier
@@ -425,9 +426,16 @@ static void Rivet_ChildInit (apr_pool_t *pChild, server_rec *server)
     Tcl_InitNotifier();
 #endif
 
+    /* We can rely on the existence of module_globals only we are
+     * running the prefork MPM, otherwise the pointer is NULL and
+     * the structure need to be filled
+     */
+
     if (module_globals == NULL)
     {
-        module_globals = Rivet_CreateModuleGlobals (pChild,server);
+        module_globals = Rivet_CreateModuleGlobals (pChild);
+        module_globals->rivet_mpm_bridge = Rivet_SeekMPMBridge(pChild);
+        module_globals->server = server;
     }
 
     /* This mutex should protect the process wide pool from concurrent access by 
@@ -481,6 +489,14 @@ static int Rivet_Handler (request_rec *r)
     return (*RIVET_MPM_BRIDGE_FUNCTION(request_processor))(r,ctype);
 }
 
+static int Rivet_InitGlobals (apr_pool_t *pPool, apr_pool_t *pLog, apr_pool_t *pTemp)
+{
+    /* the module global structure is allocated and the MPM bridge name established */
+
+    module_globals = Rivet_CreateModuleGlobals (pPool);
+    return OK;
+}
+
 /*
  * -- rivet_register_hooks: mod_rivet basic setup.
  *
@@ -489,6 +505,7 @@ static int Rivet_Handler (request_rec *r)
 
 static void rivet_register_hooks(apr_pool_t *p)
 {
+    ap_hook_pre_config  (Rivet_InitGlobals,NULL, NULL, APR_HOOK_LAST);
     ap_hook_post_config (Rivet_ServerInit, NULL, NULL, APR_HOOK_LAST);
     ap_hook_handler     (Rivet_Handler,    NULL, NULL, APR_HOOK_MIDDLE);
     ap_hook_child_init  (Rivet_ChildInit,  NULL, NULL, APR_HOOK_LAST);
diff --git a/src/mod_rivet_ng/mod_rivet.h b/src/mod_rivet_ng/mod_rivet.h
index 2a43998..681c559 100644
--- a/src/mod_rivet_ng/mod_rivet.h
+++ b/src/mod_rivet_ng/mod_rivet.h
@@ -120,31 +120,23 @@ typedef struct _rivet_server_conf {
 
     unsigned int user_scripts_status;
 
-    int             default_cache_size;
-    int             upload_max;
-    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
-                                               exported ::rivet commands                    */
-    char*           server_name;
-    const char*     upload_dir;
-    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                                            */
-    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 *
-                                         * be composed using the pattern 'rivet_(mpm_bridge)_mpm.so     */
+    int          default_cache_size;
+    int          upload_max;
+    int          upload_files_to_var;
+    int          honor_header_only_reqs;
+
+    int          export_rivet_ns;        /* export the ::rivet namespace commands        */
+    int          import_rivet_ns;        /* import into the global namespace the
+                                            exported ::rivet commands                    */
+    char*        server_name;
+    const char*  upload_dir;
+    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                                      */
 } rivet_server_conf;
 
 #define TCL_INTERPS 1
@@ -211,7 +203,19 @@ typedef struct _mod_rivet_globals {
                         server_interp;          /* server and prefork MPM interpreter       */
     apr_thread_mutex_t* pool_mutex;             /* threads commmon pool mutex               */
     rivet_bridge_table* bridge_jump_table;      /* Jump table to bridge specific procedures */
+    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 be composed using */
+                                                /* the pattern 'rivet_(mpm_bridge)_mpm.so   */
     mpm_bridge_status*  mpm;                    /* bridge private control structure         */
+    int                 single_thread_exit;     /* With a threaded bridge allow a single    */
+                                                /* thread to exit instead of forcing the    */
+                                                /* whole process to terminate               */
+    int                 separate_virtual_interps; 
+                                                /* Virtual host have their own interpreter  */
+    int                 separate_channels;      /* when true a vhosts get their private channel */
 #ifdef RIVET_SERIALIZE_HTTP_REQUESTS
     apr_thread_mutex_t* req_mutex;
 #endif
@@ -291,6 +295,12 @@ Tcl_Obj* Rivet_CurrentServerRec (Tcl_Interp* interp, server_rec* s);
 #define ABORTPAGE_CODE              "ABORTPAGE"
 #define THREAD_EXIT_CODE            "THREAD_EXIT"
 
+/* Configuration defaults */
+
+#define SINGLE_THREAD_EXIT_UNDEF   -1    /* pre config undefined value for single 
+                                            thread exit flag in the module globals
+                                            structure */
+
 #define TCL_MAX_CHANNEL_BUFFER_SIZE (1024*1024)
 #define MODNAME                     "mod_rivet"
 
diff --git a/src/mod_rivet_ng/mod_rivet_common.c b/src/mod_rivet_ng/mod_rivet_common.c
index f7931d7..e26f2ea 100644
--- a/src/mod_rivet_ng/mod_rivet_common.c
+++ b/src/mod_rivet_ng/mod_rivet_common.c
@@ -214,7 +214,6 @@ void Rivet_ReleasePerDirScripts(rivet_thread_interp* rivet_interp)
     }
 
     apr_hash_clear(ht);
-
 }
 
 
@@ -364,9 +363,7 @@ rivet_thread_interp* Rivet_NewVHostInterp(apr_pool_t *pool,server_rec* server)
         interp_obj->cache_size = rsc->default_cache_size;
     }
 
-    if (interp_obj->cache_size > 0) {
-        interp_obj->cache_free = interp_obj->cache_size;
-    }
+    interp_obj->cache_free = interp_obj->cache_size;
 
     /* we now create memory from the cache pool as subpool of the thread private pool */
  
diff --git a/src/mod_rivet_ng/rivetInspect.c b/src/mod_rivet_ng/rivetInspect.c
index 5424ea8..d408908 100644
--- a/src/mod_rivet_ng/rivetInspect.c
+++ b/src/mod_rivet_ng/rivetInspect.c
@@ -21,8 +21,6 @@
    limitations under the License.
 */
 
-/* $Id: */
-
 #include <tcl.h>
 #include <string.h>
 #include <apr_errno.h>
@@ -88,6 +86,8 @@ enum confIndices {
                     conf_index_terminator 
 };
 
+extern mod_rivet_globals* module_globals;
+
 /* 
  * -- Rivet_ReadConfParameter
  *
@@ -139,11 +139,11 @@ Rivet_ReadConfParameter ( Tcl_Interp*        interp,
         case abort_script:              string_value = rsc->rivet_abort_script; break;
         case error_script:              string_value = rsc->rivet_error_script; break;
         case upload_directory:          string_value = (char *)rsc->upload_dir; break;
-        case mpm_bridge:                string_value = (char *)rsc->mpm_bridge; break;
+        case mpm_bridge:                string_value = (char *)module_globals->mpm_bridge; break;
         case upload_max:                int_value = Tcl_NewIntObj(rsc->upload_max); break;
         case upload_files_to_var:       int_value = Tcl_NewIntObj(rsc->upload_files_to_var); break;
-        case separate_virtual_interps:  int_value = Tcl_NewIntObj(rsc->separate_virtual_interps); break;
-        case separate_channels:         int_value = Tcl_NewIntObj(rsc->separate_channels); break;
+        case separate_virtual_interps:  int_value = Tcl_NewIntObj(module_globals->separate_virtual_interps); break;
+        case separate_channels:         int_value = Tcl_NewIntObj(module_globals->separate_channels); break;
         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;
diff --git a/src/mod_rivet_ng/rivet_lazy_mpm.c b/src/mod_rivet_ng/rivet_lazy_mpm.c
index 40f68b6..eecc1c7 100644
--- a/src/mod_rivet_ng/rivet_lazy_mpm.c
+++ b/src/mod_rivet_ng/rivet_lazy_mpm.c
@@ -505,11 +505,11 @@ int LazyBridge_ExitHandler(rivet_thread_private* private)
 
     private->ext->keep_going = 0;
 
-    if (!private->running_conf->single_thread_exit)
+    if (!module_globals->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() */
+        /* 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() */
      
         LazyBridge_Finalize(private->r->server);
 
@@ -518,9 +518,30 @@ int LazyBridge_ExitHandler(rivet_thread_private* private)
     return TCL_OK;
 }
 
+/*
+ *  -- LazyBridge_ServerInit
+ *
+ * Bridge server wide inizialization:
+ *
+ *  We set the default value of the flag single_thread_exit 
+ *  stored in the module globals
+ *
+ */
+
+int LazyBridge_ServerInit (apr_pool_t* pPool,apr_pool_t* pLog,apr_pool_t* pTemp,server_rec* s)
+{
+    if (module_globals->single_thread_exit == SINGLE_THREAD_EXIT_UNDEF)
+    {
+        module_globals->single_thread_exit = 1;
+    }
+    return OK;
+}
+
+/* Table of bridge control functions */
+
 DLLEXPORT
 RIVET_MPM_BRIDGE {
-    NULL,
+    LazyBridge_ServerInit,
     LazyBridge_ChildInit,
     LazyBridge_Request,
     LazyBridge_Finalize,
diff --git a/src/mod_rivet_ng/rivet_prefork_mpm.c b/src/mod_rivet_ng/rivet_prefork_mpm.c
index 3c20250..6d04bd0 100644
--- a/src/mod_rivet_ng/rivet_prefork_mpm.c
+++ b/src/mod_rivet_ng/rivet_prefork_mpm.c
@@ -191,9 +191,30 @@ rivet_thread_interp* PreforkBridge_Interp (rivet_thread_private* private,
     return private->ext->interps[conf->idx];   
 }
 
+/*
+ *  -- PreforkBridge_ServerInit
+ *
+ * Bridge server wide inizialization:
+ *
+ *  We set the default value of the flag single_thread_exit 
+ *  stored in the module globals
+ *
+ */
+
+int PreforkBridge_ServerInit (apr_pool_t* pPool,apr_pool_t* pLog,apr_pool_t* pTemp,server_rec* s)
+{
+    if (module_globals->single_thread_exit == SINGLE_THREAD_EXIT_UNDEF)
+    {
+        module_globals->single_thread_exit = 0;
+    }
+    return OK;
+}
+
+/* Table of bridge control functions */
+
 DLLEXPORT
 RIVET_MPM_BRIDGE {
-    NULL,
+    PreforkBridge_ServerInit,
     PreforkBridge_ChildInit,
     PreforkBridge_Request,
     PreforkBridge_Finalize,
diff --git a/src/mod_rivet_ng/rivet_worker_mpm.c b/src/mod_rivet_ng/rivet_worker_mpm.c
index b78064c..ec9885f 100644
--- a/src/mod_rivet_ng/rivet_worker_mpm.c
+++ b/src/mod_rivet_ng/rivet_worker_mpm.c
@@ -784,7 +784,7 @@ int WorkerBridge_ExitHandler(rivet_thread_private* private)
     //module_globals->mpm->exit_command = 1;
     //module_globals->mpm->exit_command_status = private->exit_status;
 
-    if (!private->running_conf->single_thread_exit)
+    if (!module_globals->single_thread_exit)
     {
 
         module_globals->mpm->skip_thread_on_exit = 1;
@@ -847,9 +847,30 @@ rivet_thread_interp* WorkerBridge_Interp (rivet_thread_private* private,
     return private->ext->interps[conf->idx];   
 }
 
+/*
+ *  -- WorkerBridge_ServerInit
+ *
+ * Bridge server wide inizialization:
+ *
+ *  We set the default value of the flag single_thread_exit 
+ *  stored in the module globals
+ *
+ */
+
+int WorkerBridge_ServerInit (apr_pool_t* pPool,apr_pool_t* pLog,apr_pool_t* pTemp,server_rec* s)
+{
+    if (module_globals->single_thread_exit == SINGLE_THREAD_EXIT_UNDEF)
+    {
+        module_globals->single_thread_exit = 1;
+    }
+    return OK;
+}
+
+/* Table of bridge control functions */
+
 DLLEXPORT
 RIVET_MPM_BRIDGE {
-    NULL,
+    WorkerBridge_ServerInit,
     WorkerBridge_ChildInit,
     WorkerBridge_Request,
     WorkerBridge_Finalize,
diff --git a/src/mod_rivet_ng/worker_prefork_common.c b/src/mod_rivet_ng/worker_prefork_common.c
index 17b2dac..0251185 100644
--- a/src/mod_rivet_ng/worker_prefork_common.c
+++ b/src/mod_rivet_ng/worker_prefork_common.c
@@ -36,7 +36,7 @@
 
 extern DLLIMPORT mod_rivet_globals* module_globals;
 extern DLLIMPORT apr_threadkey_t*   rivet_thread_key;
-extern DLLIMPORT module rivet_module;
+extern DLLIMPORT module             rivet_module;
 
 extern rivet_thread_interp* MPM_MasterInterp(server_rec* s);
 
@@ -151,10 +151,10 @@ rivet_thread_private* Rivet_VirtualHostsInterps (rivet_thread_private* private)
         }
         else 
         {
-            if (root_server_conf->separate_virtual_interps)
+            if (module_globals->separate_virtual_interps)
             {
                 rivet_interp = Rivet_NewVHostInterp(private->pool,s);
-                if (myrsc->separate_channels)
+                if (module_globals->separate_channels)
                 {
                     rivet_interp->channel = Rivet_CreateRivetChannel(private->pool,rivet_thread_key);
                     Tcl_RegisterChannel(rivet_interp->interp,*rivet_interp->channel);
@@ -202,7 +202,7 @@ rivet_thread_private* Rivet_VirtualHostsInterps (rivet_thread_private* private)
 
         function = myrsc->rivet_child_init_script;
         if (function && 
-            (s == root_server || root_server_conf->separate_virtual_interps || function != parentfunction))
+            (s == root_server || module_globals->separate_virtual_interps || function != parentfunction))
         {
             char*       errmsg = MODNAME ": Error in Child init script: %s";
             Tcl_Interp* interp = rivet_interp->interp;
@@ -271,7 +271,6 @@ void Rivet_ProcessorCleanup (void *data)
 {
     int                     i;
     rivet_thread_private*   private = (rivet_thread_private *) data;
-    rivet_server_conf*      rsc = RIVET_SERVER_CONF(module_globals->server->module_config);
 
     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, module_globals->server, 
                  "Thread exiting after %d requests served (%d vhosts)", 
@@ -298,7 +297,7 @@ void Rivet_ProcessorCleanup (void *data)
 
         RivetCache_Cleanup(private,private->ext->interps[i]);
 
-        if ((i > 0) && rsc->separate_channels) 
+        if ((i > 0) && module_globals->separate_channels) 
             Rivet_ReleaseRivetChannel(private->ext->interps[i]->interp,private->channel);
 
         Tcl_DeleteInterp(private->ext->interps[i]->interp);
@@ -317,6 +316,6 @@ void Rivet_ProcessorCleanup (void *data)
          * in private->ext->interps[0]
          */
 
-    } while ((++i < module_globals->vhosts_count) && rsc->separate_virtual_interps);
+    } while ((++i < module_globals->vhosts_count) && module_globals->separate_virtual_interps);
 
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@tcl.apache.org
For additional commands, e-mail: commits-help@tcl.apache.org