You are viewing a plain text version of this content. The canonical link for it is here.
Posted to site-cvs@tcl.apache.org by mx...@apache.org on 2015/12/16 10:37:58 UTC

svn commit: r1720310 - in /tcl/rivet/trunk: ./ doc/xml/ rivet/packages/asciiglyphs/ src/ src/mod_rivet/

Author: mxmanghi
Date: Wed Dec 16 09:37:58 2015
New Revision: 1720310

URL: http://svn.apache.org/viewvc?rev=1720310&view=rev
Log:
    * src/mod_rivet/rivet_lazy_mpm.c: new lazy MPM bridge with a smoother workload 
    balancing (should work better for low to middle workloads)
    * src/mod_rivet/rivet_worker_mpm.c: improved code comments
    * src/mod_rivet/mod_rivet.c: handling of mpm_bridge configuration parameter.
    New bridge module search method
    * src/mod_rivet/rivet_config.c: new MpmBridge configuration directive



Added:
    tcl/rivet/trunk/src/mod_rivet/rivet_lazy_mpm.c
      - copied, changed from r1720309, tcl/rivet/trunk/src/mod_rivet/rivet_aprthread_mpm.c
Removed:
    tcl/rivet/trunk/src/mod_rivet/rivet_aprthread_mpm.c
Modified:
    tcl/rivet/trunk/ChangeLog
    tcl/rivet/trunk/doc/xml/commands.xml
    tcl/rivet/trunk/rivet/packages/asciiglyphs/asciiglyphs.tcl
    tcl/rivet/trunk/src/Makefile.am
    tcl/rivet/trunk/src/mod_rivet/apache_config.c
    tcl/rivet/trunk/src/mod_rivet/mod_rivet.c
    tcl/rivet/trunk/src/mod_rivet/mod_rivet.h
    tcl/rivet/trunk/src/mod_rivet/rivet_worker_mpm.c

Modified: tcl/rivet/trunk/ChangeLog
URL: http://svn.apache.org/viewvc/tcl/rivet/trunk/ChangeLog?rev=1720310&r1=1720309&r2=1720310&view=diff
==============================================================================
--- tcl/rivet/trunk/ChangeLog (original)
+++ tcl/rivet/trunk/ChangeLog Wed Dec 16 09:37:58 2015
@@ -1,3 +1,11 @@
+2015-12-15 Massimo Manghi <mx...@apache.org>
+    * src/mod_rivet/rivet_lazy_mpm.c: new lazy MPM bridge with a smoother workload 
+    balancing (should work better for low to middle workloads)
+    * src/mod_rivet/rivet_worker_mpm.c: improved code comments
+    * src/mod_rivet/mod_rivet.c: handling of mpm_bridge configuration parameter.
+    New bridge module search method
+    * src/mod_rivet/rivet_config.c: new MpmBridge configuration directive
+
 2015-12-13 Massimo Manghi <mx...@apache.org>
     * src/mod_rivet/rivet_worker_mpm.c: changed in order to have a better handling
     of ::rivet::exit (the call to exit( ) is now carried out from within the

Modified: tcl/rivet/trunk/doc/xml/commands.xml
URL: http://svn.apache.org/viewvc/tcl/rivet/trunk/doc/xml/commands.xml?rev=1720310&r1=1720309&r2=1720310&view=diff
==============================================================================
--- tcl/rivet/trunk/doc/xml/commands.xml (original)
+++ tcl/rivet/trunk/doc/xml/commands.xml Wed Dec 16 09:37:58 2015
@@ -1576,6 +1576,11 @@ bab</programlisting>
 				as a replacement for Tcl's own <command>try</command> and it's needed
 				if you want <arg>script</arg> to safely bail out to <command>AbortScript</command>	
 			</para>
+			<note>
+				This command is not exported from the <command>::rivet</command> namespace and therefore has
+				to be fully qualified.
+			</note>
+
 			<para>
 				This script shows how <command>::rivet:try</command>
 				handles different exceptions or errors. You can drive this script

Modified: tcl/rivet/trunk/rivet/packages/asciiglyphs/asciiglyphs.tcl
URL: http://svn.apache.org/viewvc/tcl/rivet/trunk/rivet/packages/asciiglyphs/asciiglyphs.tcl?rev=1720310&r1=1720309&r2=1720310&view=diff
==============================================================================
--- tcl/rivet/trunk/rivet/packages/asciiglyphs/asciiglyphs.tcl (original)
+++ tcl/rivet/trunk/rivet/packages/asciiglyphs/asciiglyphs.tcl Wed Dec 16 09:37:58 2015
@@ -50,7 +50,7 @@ namespace eval ::AsciiGlyphs:: {
         variable glyphs_avail
 
         #if {![string is xdigit $c]} 
-        puts -nonewline "'$c' -> "
+        #puts -nonewline "'$c' -> "
         if {[lsearch $glyphs_avail $c] < 0} {
             #return -code error -errocode invalid_char "Invalid non hexadecimal or non space character"
             if {[string is space $c]} {
@@ -61,7 +61,7 @@ namespace eval ::AsciiGlyphs:: {
                 set c "*"
             }
         }
-        puts $c
+        #puts $c
 
         set lines [split $ASCIIGLYPHS($c) "\n"]
         set lines [lrange $lines 1 end-1]

Modified: tcl/rivet/trunk/src/Makefile.am
URL: http://svn.apache.org/viewvc/tcl/rivet/trunk/src/Makefile.am?rev=1720310&r1=1720309&r2=1720310&view=diff
==============================================================================
--- tcl/rivet/trunk/src/Makefile.am (original)
+++ tcl/rivet/trunk/src/Makefile.am Wed Dec 16 09:37:58 2015
@@ -54,7 +54,7 @@ mod_rivet_la_LIBADD = @TCL_LIBS@ @APXS_L
 mod_rivet_la_CPPFLAGS = -I@rivet_core@ -I@rivet_channel@ -I@RIVET_BASE_INCLUDE@/parser -I@apache_request@ @apache_include@ -I@RIVET_BASE_INCLUDE@ @TCL_INCLUDES@ @APXS_CPPFLAGS@ @APXS_INCLUDES@ @APR_CPPFLAGS@ @APR_INCLUDES@ @APU_INCLUDES@ -DSTART_TAG='"<?"' -DEND_TAG='"?>"'
 
 lib_libmpmdir = @RIVET_TCL_TARGET@/mpm
-lib_libmpm_LTLIBRARIES = rivet_worker_mpm.la rivet_prefork_mpm.la 
+lib_libmpm_LTLIBRARIES = rivet_worker_mpm.la rivet_prefork_mpm.la rivet_lazy_mpm.la
 
 rivet_worker_mpm_la_SOURCES = @rivet_core@/rivet_worker_mpm.c
 rivet_worker_mpm_la_LDFLAGS = @TCL_STUB_LIB_SPEC@ @APXS_LDFLAGS@ -module -avoid-version
@@ -66,10 +66,10 @@ rivet_prefork_mpm_la_LDFLAGS = @TCL_STUB
 rivet_prefork_mpm_la_LIBADD  = @APXS_LIBS@
 rivet_prefork_mpm_la_CPPFLAGS = @apache_include@ -I@rivet_core@ @TCL_INCLUDES@ @APXS_CPPFLAGS@ @APXS_INCLUDES@ @APR_CPPFLAGS@ @APR_INCLUDES@ @APU_INCLUDES@ -I@apache_request@ -I@RIVET_BASE_INCLUDE@
 
-#rivet_aprthread_mpm_la_SOURCES = @rivet_core@/rivet_aprthread_mpm.c
-#rivet_aprthread_mpm_la_LDFLAGS = @TCL_STUB_LIB_SPEC@ @APXS_LDFLAGS@ -module -avoid-version
-#rivet_aprthread_mpm_la_LIBADD  = @APXS_LIBS@
-#rivet_aprthread_mpm_la_CPPFLAGS = @apache_include@ -I@rivet_core@ @TCL_INCLUDES@ @APXS_CPPFLAGS@ @APXS_INCLUDES@ @APR_CPPFLAGS@ @APR_INCLUDES@ @APU_INCLUDES@ -I@apache_request@ -I@RIVET_BASE_INCLUDE@
+rivet_lazy_mpm_la_SOURCES = @rivet_core@/rivet_lazy_mpm.c
+rivet_lazy_mpm_la_LDFLAGS = @TCL_STUB_LIB_SPEC@ @APXS_LDFLAGS@ -module -avoid-version
+rivet_lazy_mpm_la_LIBADD  = @APXS_LIBS@
+rivet_lazy_mpm_la_CPPFLAGS = @apache_include@ -I@rivet_core@ @TCL_INCLUDES@ @APXS_CPPFLAGS@ @APXS_INCLUDES@ @APR_CPPFLAGS@ @APR_INCLUDES@ @APU_INCLUDES@ -I@apache_request@ -I@RIVET_BASE_INCLUDE@
 
 # Removing libtool .la files from installation
 

Modified: tcl/rivet/trunk/src/mod_rivet/apache_config.c
URL: http://svn.apache.org/viewvc/tcl/rivet/trunk/src/mod_rivet/apache_config.c?rev=1720310&r1=1720309&r2=1720310&view=diff
==============================================================================
--- tcl/rivet/trunk/src/mod_rivet/apache_config.c (original)
+++ tcl/rivet/trunk/src/mod_rivet/apache_config.c Wed Dec 16 09:37:58 2015
@@ -230,6 +230,7 @@ Rivet_CopyConfig( rivet_server_conf *old
     newrsc->rivet_user_vars = oldrsc->rivet_user_vars;
     newrsc->idx = oldrsc->idx;
     newrsc->path = oldrsc->path;
+    newrsc->mpm_bridge = oldrsc->mpm_bridge;
     //newrsc->user_conf = oldrsc->user_conf;
     newrsc->user_scripts_status = oldrsc->user_scripts_status;
 }
@@ -416,6 +417,7 @@ Rivet_MergeConfig(apr_pool_t *p, void *b
     rsc->separate_virtual_interps = base->separate_virtual_interps;
     rsc->honor_header_only_reqs = base->honor_header_only_reqs;
     rsc->separate_channels = base->separate_channels;
+    rsc->mpm_bridge = base->mpm_bridge;
 
     RIVET_CONF_SELECT(rsc,base,overrides,upload_dir)
     RIVET_CONF_SELECT(rsc,base,overrides,rivet_server_vars)
@@ -466,6 +468,7 @@ Rivet_CreateConfig(apr_pool_t *p, server
     rsc->separate_channels          = RIVET_SEPARATE_CHANNELS;
     rsc->upload_dir                 = RIVET_UPLOAD_DIR;
     rsc->server_name                = 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 );
@@ -610,6 +613,7 @@ Rivet_DirConf(cmd_parms *cmd,void *vrdc,
  *  RivetServerConf UploadFilesToVar <yes|no>
  *  RivetServerConf SeparateVirtualInterps <yes|no>
  *  RivetServerConf HonorHeaderOnlyRequests <yes|no> (2008-06-20: mm)
+ *  RivetServerConf MpmBridge <path-to-mpm-bridge>|<bridge-label> (2015-12-14: mm)
  */
 
 const char *
@@ -625,20 +629,22 @@ Rivet_ServerConf(cmd_parms *cmd,void *du
         return "Rivet Error: RivetServerConf requires two arguments";
     }
 
-    if( STREQU( var, "CacheSize" ) ) {
+    if ( STREQU ( var, "CacheSize" ) ) {
         rsc->default_cache_size = strtol( val, NULL, 10 );
-    } else if( STREQU( var, "UploadDirectory" ) ) {
+    } else if ( STREQU ( var, "UploadDirectory" ) ) {
         rsc->upload_dir = val;
-    } else if( STREQU( var, "UploadMaxSize" ) ) {
+    } else if ( STREQU ( var, "UploadMaxSize" ) ) {
         rsc->upload_max = strtol( val, NULL, 10 );
-    } else if( STREQU( var, "UploadFilesToVar" ) ) {
+    } else if ( STREQU ( var, "UploadFilesToVar" ) ) {
         Tcl_GetBoolean (NULL, val, &rsc->upload_files_to_var);
-    } else if( STREQU( var, "SeparateVirtualInterps" ) ) {
+    } else if ( STREQU ( var, "SeparateVirtualInterps" ) ) {
         Tcl_GetBoolean (NULL, val, &rsc->separate_virtual_interps);
-    } else if( STREQU( var, "HonorHeaderOnlyRequests" ) ) {
+    } else if ( STREQU ( var, "HonorHeaderOnlyRequests" ) ) {
         Tcl_GetBoolean (NULL, val, &rsc->honor_header_only_reqs);
-    } else if( STREQU( var, "SeparateChannels" ) ) {
+    } else if ( STREQU ( var, "SeparateChannels" ) ) {
         Tcl_GetBoolean (NULL, val, &rsc->separate_channels);
+    } else if ( STREQU ( var, "MpmBridge" ) ) {
+        rsc->mpm_bridge = val;
     } else {
         string = Rivet_SetScript( cmd->pool, rsc, var, val);
     }

Modified: tcl/rivet/trunk/src/mod_rivet/mod_rivet.c
URL: http://svn.apache.org/viewvc/tcl/rivet/trunk/src/mod_rivet/mod_rivet.c?rev=1720310&r1=1720309&r2=1720310&view=diff
==============================================================================
--- tcl/rivet/trunk/src/mod_rivet/mod_rivet.c (original)
+++ tcl/rivet/trunk/src/mod_rivet/mod_rivet.c Wed Dec 16 09:37:58 2015
@@ -300,7 +300,12 @@ rivet_thread_private* Rivet_VirtualHosts
     
     root_interp = (*RIVET_MPM_BRIDGE_FUNCTION(mpm_master_interp))();
 
-    /* we must assume the module was able to create the root interprter */ 
+    /* we must assume the module was able to create the root interprter otherwise
+     * it's just a null module. I try to have also this case to develop experimental
+     * bridges without the Tcl stuff 
+     */ 
+
+    //if (root_interp == NULL) return private;
 
     ap_assert (root_interp != NULL);
 
@@ -419,11 +424,9 @@ rivet_thread_private* Rivet_VirtualHosts
                 ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, root_server,
                              errmsg, function);
                 ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, root_server, 
-                             "errorCode: %s",
-                                Tcl_GetVar(interp, "errorCode", 0));
+                             "errorCode: %s", Tcl_GetVar(interp, "errorCode", 0));
                 ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, root_server, 
-                             "errorInfo: %s",
-                        Tcl_GetVar(interp, "errorInfo", 0));
+                             "errorInfo: %s", Tcl_GetVar(interp, "errorInfo", 0));
             }
             Tcl_Release (interp);
             Tcl_DecrRefCount(tcl_child_init);
@@ -500,8 +503,8 @@ Rivet_SendContent(rivet_thread_private *
 
                 newconfig = RIVET_NEW_CONF(private->r->pool);
 
-                Rivet_CopyConfig( private->running_conf, newconfig );
-                Rivet_MergeDirConfigVars( private->r->pool, newconfig, private->running_conf, rdc );
+                Rivet_CopyConfig (private->running_conf,newconfig);
+                Rivet_MergeDirConfigVars (private->r->pool,newconfig,private->running_conf,rdc);
                 private->running_conf = newconfig;
 
                 scripts = Rivet_RunningScripts (private->pool,scripts,newconfig);
@@ -1396,56 +1399,69 @@ Rivet_RunServerInit (apr_pool_t *pPool,
     }
 
     return OK;
-
 }
 
-/* -- Rivet_ServerInit
+/*
+ * -- Rivet_SeekMPMBridge 
+ *
  *
  */
 
-static int
-Rivet_ServerInit (apr_pool_t *pPool, apr_pool_t *pLog, apr_pool_t *pTemp, server_rec *server)
+static char*
+Rivet_SeekMPMBridge (apr_pool_t* pool,server_rec* server)
 {
-    char*               mpm_prefork_bridge = "rivet_prefork_mpm.so";
-    char*               mpm_worker_bridge  = "rivet_worker_mpm.so";
-    char*               mpm_model_path;
-    int                 ap_mpm_result;
-    apr_dso_handle_t*   dso_handle;
+    char*   mpm_prefork_bridge = "rivet_prefork_mpm.so";
+    char*   mpm_worker_bridge  = "rivet_worker_mpm.so";
+    char*   mpm_model_path;
+    int     ap_mpm_result;
+    rivet_server_conf* rsc = RIVET_SERVER_CONF( server->module_config );
 
-#if RIVET_DISPLAY_VERSION
-    ap_add_version_component(pPool,RIVET_PACKAGE_NAME"/"RIVET_VERSION);
-#else
-    ap_add_version_component(pPool,RIVET_PACKAGE_NAME);
-#endif
-
-    /* Everything revolves around this structure */
+    /* With the env variable RIVET_MPM_BRIDGE we have the chance to tell mod_rivet 
+       what bridge custom implementation we want to be loaded */
 
-    module_globals = apr_palloc(pPool,sizeof(mod_rivet_globals));
+    if (apr_env_get (&mpm_model_path,"RIVET_MPM_BRIDGE",pool) == APR_SUCCESS)
+    {
+        return mpm_model_path;
+    }
 
-    /* Creating the module global pool */
+    /* we now look into the configuration record */
 
-    if (apr_pool_create(&module_globals->pool, NULL) != APR_SUCCESS) 
+    if (rsc->mpm_bridge != NULL)
     {
-        ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, server, 
-                     MODNAME ": could not initialize mod_rivet private pool");
-        exit(1);
+        apr_finfo_t finfo;
+
+        mpm_model_path = apr_pstrcat(pool,RIVET_DIR,"/mpm/rivet_",rsc->mpm_bridge,"_mpm.so",NULL);
+        if (apr_stat(&finfo,mpm_model_path,APR_FINFO_MIN,pool) == APR_SUCCESS)
+        {
+            return mpm_model_path;
+        }
+
+        if (apr_stat(&finfo,rsc->mpm_bridge,APR_FINFO_MIN,pool) == APR_SUCCESS)
+        {
+            return apr_pstrdup(pool,rsc->mpm_bridge);
+        }
+        else
+        {   
+            ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, server, 
+                         MODNAME ": MPM bridge %s not found", rsc->mpm_bridge); 
+            exit(1);   
+        }
+
     }
 
     /* Let's load the Rivet-MPM bridge */
 
-    module_globals->rivet_mpm_bridge = mpm_worker_bridge;
     if (ap_mpm_query(AP_MPMQ_IS_THREADED,&ap_mpm_result) == APR_SUCCESS)
     {
-
         if (ap_mpm_result == AP_MPMQ_NOT_SUPPORTED)
         {
             /* we are forced to load the prefork MPM bridge */
 
-            module_globals->rivet_mpm_bridge = apr_pstrdup(pPool,mpm_prefork_bridge);
+            mpm_model_path = apr_pstrdup(pool,mpm_prefork_bridge);
         }
         else
         {
-            module_globals->rivet_mpm_bridge = apr_pstrdup(pPool,mpm_worker_bridge);
+            mpm_model_path = apr_pstrdup(pool,mpm_worker_bridge);
         }
     }
     else
@@ -1456,25 +1472,56 @@ Rivet_ServerInit (apr_pool_t *pPool, apr
          * give a default to the MPM bridge anyway
          */
 
-        module_globals->rivet_mpm_bridge = apr_pstrdup(pPool,mpm_worker_bridge);
+        mpm_model_path = apr_pstrdup(pool,mpm_worker_bridge);
     }
 
-    /* With the env variable RIVET_MPM_BRIDGE we have the chance to tell mod_rivet 
-       what bridge custom implementation we want to be loaded */
+    mpm_model_path = apr_pstrcat(pool,RIVET_DIR,"/mpm/",mpm_model_path,NULL);
+    return mpm_model_path;
+}
+
+
+/* -- Rivet_ServerInit
+ *
+ * Post config hook. The server initialization loads the MPM bridge
+ * and runs the Tcl server initialization script
+ *
+ */
+
+static int
+Rivet_ServerInit (apr_pool_t *pPool, apr_pool_t *pLog, apr_pool_t *pTemp, server_rec *server)
+{
+    apr_dso_handle_t*   dso_handle;
+
+#if RIVET_DISPLAY_VERSION
+    ap_add_version_component(pPool,RIVET_PACKAGE_NAME"/"RIVET_VERSION);
+#else
+    ap_add_version_component(pPool,RIVET_PACKAGE_NAME);
+#endif
 
-    if (apr_env_get (&mpm_model_path,"RIVET_MPM_BRIDGE",pTemp) != APR_SUCCESS)
+    /* Everything revolves around this structure */
+
+    module_globals = apr_palloc(pPool,sizeof(mod_rivet_globals));
+
+    /* Creating the module global pool */
+
+    if (apr_pool_create(&module_globals->pool, NULL) != APR_SUCCESS) 
     {
-        mpm_model_path = apr_pstrcat(pTemp,RIVET_DIR,"/mpm/",module_globals->rivet_mpm_bridge,NULL);
-    } 
+        ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, server, 
+                     MODNAME ": could not initialize mod_rivet private pool");
+        exit(1);
+    }
+
+    module_globals->rivet_mpm_bridge = Rivet_SeekMPMBridge(pTemp,server);
 
     /* Finally the bridge is loaded and the jump table sought */
 
-    if (apr_dso_load(&dso_handle,mpm_model_path,pPool) == APR_SUCCESS)
+    if (apr_dso_load(&dso_handle,module_globals->rivet_mpm_bridge,pPool) == APR_SUCCESS)
     {
         apr_status_t                rv;
         apr_dso_handle_sym_t        func = NULL;
 
-        ap_log_error(APLOG_MARK,APLOG_DEBUG,0,server,"MPM bridge loaded: %s",mpm_model_path);
+        ap_log_error(APLOG_MARK,APLOG_DEBUG,0,server,
+                     "MPM bridge loaded: %s",module_globals->rivet_mpm_bridge);
 
         rv = apr_dso_sym(&func,dso_handle,"bridge_jump_table");
         if (rv == APR_SUCCESS)

Modified: tcl/rivet/trunk/src/mod_rivet/mod_rivet.h
URL: http://svn.apache.org/viewvc/tcl/rivet/trunk/src/mod_rivet/mod_rivet.h?rev=1720310&r1=1720309&r2=1720310&view=diff
==============================================================================
--- tcl/rivet/trunk/src/mod_rivet/mod_rivet.h (original)
+++ tcl/rivet/trunk/src/mod_rivet/mod_rivet.h Wed Dec 16 09:37:58 2015
@@ -122,6 +122,10 @@ typedef struct _rivet_server_conf {
     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     */
 } rivet_server_conf;
 
 #define TCL_INTERPS 1

Copied: tcl/rivet/trunk/src/mod_rivet/rivet_lazy_mpm.c (from r1720309, tcl/rivet/trunk/src/mod_rivet/rivet_aprthread_mpm.c)
URL: http://svn.apache.org/viewvc/tcl/rivet/trunk/src/mod_rivet/rivet_lazy_mpm.c?p2=tcl/rivet/trunk/src/mod_rivet/rivet_lazy_mpm.c&p1=tcl/rivet/trunk/src/mod_rivet/rivet_aprthread_mpm.c&r1=1720309&r2=1720310&rev=1720310&view=diff
==============================================================================
--- tcl/rivet/trunk/src/mod_rivet/rivet_aprthread_mpm.c (original)
+++ tcl/rivet/trunk/src/mod_rivet/rivet_lazy_mpm.c Wed Dec 16 09:37:58 2015
@@ -22,6 +22,8 @@
 /* $Id: */
 
 #include <httpd.h>
+#include <http_request.h>
+#include <ap_compat.h>
 #include <math.h>
 #include <tcl.h>
 #include <ap_mpm.h>
@@ -29,7 +31,6 @@
 
 #include "mod_rivet.h"
 #include "mod_rivet_common.h"
-#include "httpd.h"
 #include "rivetChannel.h"
 #include "apache_config.h"
 
@@ -37,191 +38,33 @@ extern mod_rivet_globals* module_globals
 extern apr_threadkey_t*  rivet_thread_key;
 extern apr_threadkey_t*  handler_thread_key;
 
-void                  Rivet_PerInterpInit(Tcl_Interp* interp, server_rec *s, apr_pool_t *p);
-//void                Rivet_ProcessorCleanup (void *data);
 rivet_thread_private* Rivet_VirtualHostsInterps (rivet_thread_private* private);
-rivet_thread_interp*         Rivet_NewVHostInterp(apr_pool_t* pool);
+rivet_thread_interp*  Rivet_NewVHostInterp(apr_pool_t* pool);
 
-/* -- supervisor_chores
- *
- */
+#define DEFAULT_HEADER_TYPE "text/html"
+#define BASIC_PAGE          "<b>Lazy Bridge</b>"
 
-#if 0
-static void supervisor_housekeeping (void)
+int Lazy_MPM_Request (request_rec* r,rivet_req_ctype ctype)
 {
-    int         nruns = module_globals->num_load_samples;
-    double      devtn;
-    double      count;
-
-    if (nruns == 60)
-    {
-        nruns = 0;
-        module_globals->average_working_threads = 0;
-    }
-
-    ++nruns;
-    count = (int) apr_atomic_read32(module_globals->running_threads_count);
-
-    devtn = ((double)count - module_globals->average_working_threads);
-    module_globals->average_working_threads += devtn / (double)nruns;
-    module_globals->num_load_samples = nruns;
-}
-#endif
-
-int Rivet_MPM_ServerInit (apr_pool_t *pPool, apr_pool_t *pLog, apr_pool_t *pTemp, server_rec *s)
-{
-    Tcl_Interp*         interp;
-    Tcl_Obj*            server_init;
-    rivet_server_conf*  rsc = RIVET_SERVER_CONF( s->module_config );
-
-    interp = Rivet_CreateTclInterp(s) ; /* Tcl server init interpreter */
-    Rivet_PerInterpInit(interp,s,pPool);
-
-    if (rsc->rivet_server_init_script != NULL) {
-        server_init = Tcl_NewStringObj(rsc->rivet_server_init_script,-1);
-        Tcl_IncrRefCount(server_init);
-
-        if (Tcl_EvalObjEx(interp, server_init, 0) != TCL_OK)
-        {
+    ap_set_content_type(r,apr_pstrdup(r->pool,DEFAULT_HEADER_TYPE));
+    ap_send_http_header(r);
 
-            ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, s, 
-                         MODNAME ": Error running ServerInitScript '%s': %s",
-                         rsc->rivet_server_init_script,
-                         Tcl_GetVar(interp, "errorInfo", 0));
-
-        } else {
-
-            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, 
-                         MODNAME ": ServerInitScript '%s' successful", 
-                         rsc->rivet_server_init_script);
-
-        }
-        Tcl_DecrRefCount(server_init);
-    }
-
-    Tcl_DeleteInterp(interp);
-
-    Tcl_SetPanicProc(Rivet_Panic);
-    return OK;
-}
-
-void Rivet_MPM_ChildInit (apr_pool_t* pool, server_rec* server)
-{
-/*
-    apr_thread_mutex_create(&module_globals->job_mutex, APR_THREAD_MUTEX_UNNESTED, pool);
-    apr_thread_cond_create(&module_globals->job_cond, pool);
-*/
-}
-
-int Rivet_MPM_Request (request_rec* r)
-{
-    rivet_thread_private*   private;
-    Tcl_Channel*            outchannel;		    /* stuff for buffering output */
-    //rivet_server_conf*      server_conf;
-    int                     retcode;
-
-    if (apr_threadkey_private_get ((void **)&private,rivet_thread_key) != APR_SUCCESS)
-    {
-        return HTTP_INTERNAL_SERVER_ERROR;
-    } 
-    else 
-    {
-
-        if (private == NULL)
-        {
-            apr_thread_mutex_lock(module_globals->pool_mutex);
-            private = apr_palloc (module_globals->pool,sizeof(*private));
-            apr_thread_mutex_unlock(module_globals->pool_mutex);
-
-            private->req_cnt    = 0;
-            private->keep_going = 1;
-            private->r          = NULL;
-            private->req        = TclWeb_NewRequestObject (module_globals->pool);
-
-            if (apr_pool_create(&private->pool, NULL) != APR_SUCCESS) 
-            {
-                ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, r->server, 
-                             MODNAME ": could not create thread private pool");
-                return HTTP_INTERNAL_SERVER_ERROR;
-            }
-
-            private->request_init = Tcl_NewStringObj("::Rivet::initialize_request\n", -1);
-            private->request_cleanup = Tcl_NewStringObj("::Rivet::cleanup_request\n", -1);
-            Tcl_IncrRefCount(private->request_init);
-            Tcl_IncrRefCount(private->request_cleanup);
-
-            /* We allocate the array for the interpreters database.
-             * Data referenced in this database must be freed by the thread before exit
-             */
-
-            private->channel    = apr_pcalloc(private->pool,sizeof(Tcl_Channel));
-            private->interps    = apr_pcalloc(private->pool,module_globals->vhosts_count*sizeof(rivet_thread_interp));
-            apr_threadkey_private_set (private,rivet_thread_key);
-            outchannel  = private->channel;
-            *outchannel = Tcl_CreateChannel(&RivetChan, "apacheout", rivet_thread_key, TCL_WRITABLE);
-
-                /* The channel we have just created replaces Tcl's stdout */
-
-            Tcl_SetStdChannel (*outchannel, TCL_STDOUT);
-
-                /* Set the output buffer size to the largest allowed value, so that we 
-                 * won't send any result packets to the browser unless the Rivet
-                 * programmer does a "flush stdout" or the page is completed.
-                 */
-
-            Tcl_SetChannelBufferSize (*outchannel, TCL_MAX_CHANNEL_BUFFER_SIZE);
-
-                /* So far nothing differs much with what we did for the prefork bridge */
-                /* At this stage we have to set up the private interpreters of configured 
-                 * virtual hosts (if any). We assume the server_rec stored in the module
-                 * globals can be used to retrieve the reference to the root interpreter
-                 * configuration and to the rivet global script
-                 */
-
-            if (Rivet_VirtualHostsInterps (private) == NULL)
-            {
-                return HTTP_INTERNAL_SERVER_ERROR;
-            }
-
-        }
-    }
-
-    private->r   = r;
-    private->req_cnt++;
-    //server_conf = RIVET_SERVER_CONF(private->r->server->module_config);
-    //TclWeb_InitRequest(private->req, private->interps[server_conf->idx]->interp, ctype, private->r);
-
-    HTTP_REQUESTS_PROC(retcode = Rivet_SendContent(private));
-
-    return retcode;
-}
-
-apr_status_t Rivet_MPM_Finalize (void* data)
-{
-/*    
-    apr_status_t  rv;
-    apr_status_t  thread_status;
-    server_rec* s = (server_rec*) data;
-
-    apr_thread_mutex_lock(module_globals->job_mutex);
-    module_globals->server_shutdown = 1;
-    apr_thread_cond_signal(module_globals->job_cond);
-    apr_thread_mutex_unlock(module_globals->job_mutex);
-
-    rv = apr_thread_join (&thread_status,module_globals->supervisor);
-    if (rv != APR_SUCCESS)
-    {
-        ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, s,
-                     MODNAME ": Error joining supervisor thread");
-    }
-*/
+    ap_rwrite(apr_pstrdup(r->pool,BASIC_PAGE),strlen(BASIC_PAGE),r);
+    ap_rflush(r);
 
-    //apr_threadkey_private_delete (rivet_thread_key);
     return OK;
 }
 
-rivet_thread_interp* Rivet_MPM_MasterInterp(apr_pool_t* pool)
+rivet_thread_interp* Lazy_MPM_MasterInterp(void)
 {
-    return Rivet_NewVHostInterp(pool);
+    return NULL;
 }
 
+RIVET_MPM_BRIDGE {
+    NULL,
+    NULL,
+    Lazy_MPM_Request,
+    NULL,
+    Lazy_MPM_MasterInterp,
+    NULL
+};

Modified: tcl/rivet/trunk/src/mod_rivet/rivet_worker_mpm.c
URL: http://svn.apache.org/viewvc/tcl/rivet/trunk/src/mod_rivet/rivet_worker_mpm.c?rev=1720310&r1=1720309&r2=1720310&view=diff
==============================================================================
--- tcl/rivet/trunk/src/mod_rivet/rivet_worker_mpm.c (original)
+++ tcl/rivet/trunk/src/mod_rivet/rivet_worker_mpm.c Wed Dec 16 09:37:58 2015
@@ -348,6 +348,17 @@ static void supervisor_housekeeping (voi
 
 /* -- threaded_bridge_supervisor
  * 
+ * This function runs within a single thread and to the
+ * start and stop of Tcl worker thread pool. It could be extended also
+ * provide some basic monitoring data. 
+ *
+ * As we don't delete Tcl interpreters anymore because it can lead
+ * to seg faults or delays the supervisor threads doesn't restart
+ * single threads anymore, but it basically stops and starts the whole
+ * pool of Tcl worker threads. Nonetheless it still keeps a list of
+ * the thread pool ids and it should be able to restart a thread when
+ * it's notified (if the child process is not shutting down)
+ *
  */
 
 static void* APR_THREAD_FUNC threaded_bridge_supervisor (apr_thread_t *thd, void *data)
@@ -454,6 +465,10 @@ void Worker_MPM_ChildInit (apr_pool_t* p
 
     module_globals->mpm = apr_pcalloc(pool,sizeof(mpm_bridge_status));
 
+    /* apr_calloc is supposed to allocate zerod memory, but we still make esplicit the initialization
+     * of some of its fields
+     */
+
     module_globals->mpm->exiting            = NULL;
     module_globals->mpm->max_threads        = 0;
     module_globals->mpm->min_spare_threads  = 0;
@@ -643,6 +658,7 @@ int Worker_MPM_Request (request_rec* r,r
             apr_thread_cond_wait(request_private->cond,request_private->mutex);
         } while (request_private->status == init); 
         apr_thread_mutex_unlock(request_private->mutex);
+
     }
     else
     {
@@ -676,6 +692,12 @@ apr_status_t Worker_MPM_Finalize (void*
     apr_thread_cond_signal(module_globals->mpm->job_cond);
     apr_thread_mutex_unlock(module_globals->mpm->job_mutex);
 
+    /* If the Function is called by the memory pool cleanup we wait
+     * to join the supervisor, otherwise we if the function was called
+     * by Worker_MPM_Exit we skip it because this thread itself must exit
+     * to allow the supervisor to exit in the shortest possible time 
+     */
+
     if (!module_globals->mpm->exit_command)
     {
         rv = apr_thread_join (&thread_status,module_globals->mpm->supervisor);
@@ -744,7 +766,8 @@ int Worker_MPM_ExitHandler(int code)
     module_globals->mpm->exit_command = 1;
     module_globals->mpm->exit_command_status = code;
 
-    /* We now tell the whole process to shutdown */
+    /* We now tell the supervisor to terminate the Tcl worker thread pool to exit
+     * and is sequence the whole process to shutdown by calling exit() */
  
     Worker_MPM_Finalize (private->r->server);
     return TCL_OK;



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