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