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/10/01 23:33:38 UTC

[tcl-rivet] branch quattuor updated (c971780 -> 395b412)

This is an automated email from the ASF dual-hosted git repository.

mxmanghi pushed a change to branch quattuor
in repository https://gitbox.apache.org/repos/asf/tcl-rivet.git.


    from c971780      * src/mod_rivet_ng/mod_rivet.[c|h]: add ap_child_shutdown flag 	* src/mod_rivet_ng/rivet_lazy_mpm.c: adding mutex protection on thread count     * src/mod_rivet_ng/rivet_worker_mpm.c: removed old code
     new a8d18e0  add support for testing with different MPMs and bridges
     new a918f36  restructuring and testing new code of upload command
     new 718a526  add add method form_exists to check for registration of a form
     new e20401c  add new entry in changelog
     new a522d75  add support for testing with different MPMs and bridges
     new 3fdb364  merging changes from master
     new 395b412  merging master into quattuor, reorganizing internal database and adding new debugging function

The 7 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .appveyor.yml                            |  39 ++++
 .gitignore                               |   1 +
 ChangeLog                                |  42 ++++
 configure.ac                             |  28 ++-
 doc/xml/directives.xml                   | 103 ++++++----
 rivet/packages/formbroker/formbroker.tcl |   8 +-
 src/TclWeb.h                             |  37 ++--
 src/mod_rivet_ng/TclWebapache.c          | 150 ++++++++------
 src/mod_rivet_ng/apache_config.c         |  37 ++--
 src/mod_rivet_ng/mod_rivet.c             | 127 +++++++-----
 src/mod_rivet_ng/mod_rivet.h             | 126 +++++++-----
 src/mod_rivet_ng/mod_rivet_cache.c       |  76 +++++--
 src/mod_rivet_ng/mod_rivet_cache.h       |   6 +-
 src/mod_rivet_ng/mod_rivet_common.c      | 100 +++++----
 src/mod_rivet_ng/mod_rivet_common.h      |   4 +-
 src/mod_rivet_ng/rivetCore.c             | 336 ++++++++++++++++++++-----------
 src/mod_rivet_ng/rivetInspect.c          |  12 +-
 src/mod_rivet_ng/rivet_lazy_mpm.c        | 101 +++++-----
 src/mod_rivet_ng/rivet_prefork_mpm.c     |  44 +++-
 src/mod_rivet_ng/rivet_worker_mpm.c      |  10 +-
 src/mod_rivet_ng/worker_prefork_common.c |  13 +-
 src/rivet.h                              |   4 +-
 tests/apachetest/apachetest.tcl          |  70 ++++---
 tests/apachetest/template.conf.2.tcl     |   1 -
 tests/runtests.tcl                       |  91 ++++++---
 25 files changed, 997 insertions(+), 569 deletions(-)


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


[tcl-rivet] 01/07: add support for testing with different MPMs and bridges

Posted by mx...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mxmanghi pushed a commit to branch quattuor
in repository https://gitbox.apache.org/repos/asf/tcl-rivet.git

commit a8d18e0e17108764f57bbc03c1ce60355064bf03
Author: Massimo Manghi <mx...@apache.org>
AuthorDate: Sun Sep 27 23:52:14 2020 +0200

    add support for testing with different MPMs and bridges
---
 .gitignore                           |  1 +
 ChangeLog                            | 15 ++++++
 tests/apachetest/apachetest.tcl      | 70 +++++++++++++++++-----------
 tests/apachetest/template.conf.2.tcl |  1 -
 tests/runtests.tcl                   | 89 ++++++++++++++++++++++++++----------
 5 files changed, 125 insertions(+), 51 deletions(-)

diff --git a/.gitignore b/.gitignore
index d6f9347..0c86a44 100644
--- a/.gitignore
+++ b/.gitignore
@@ -39,3 +39,4 @@ tests/rivet/
 tests/server.conf
 tests/test.conf
 tests/uploadedjpeg.jpg
+Session.vim
diff --git a/ChangeLog b/ChangeLog
index fd7ff00..dbe1590 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,8 +1,23 @@
+2020-09-27 Massimo Manghi <mx...@apache.org>
+	* rivet/packages/formbroker/formbroker.tcl: add method form_exists to check for registration
+	of a form
+	* test/apachetest/apachetest.tcl,test/runtests.tcl: add support for testing with various MPMs and bridges 
+
+2020-02-03 Massimo Manghi <mx...@apache.org>
+    * src/request/: Update obsolete copyright statements
+    * src/mod_rivet_ng/rivetCore.c: update comments to upload command
+    * tests: changed upload file test
+
 2020-04-16 Massimo Manghi <mx...@apache.org>
     * src/mod_rivet_ng/mod_rivet.[c|h]: add ap_child_shutdown flag
 	* src/mod_rivet_ng/rivet_lazy_mpm.c: adding mutex protection on thread count
     * src/mod_rivet_ng/rivet_worker_mpm.c: removed old code
 
+2020-04-02 Massimo Manghi <mx...@apache.org>
+    * doc/xml/formbroker.xml: fixed examples
+    * src/mod_rivet_ng/rivet_lazy_mpm.c: resolved access to shared counter
+    that was causing segfaults when child process was terminated
+
 2020-01-19 Massimo Manghi <mx...@apache.org>
     * doc/xml/commands.xml: remove entry for command incr0 (dropped in 3.0)
 
diff --git a/tests/apachetest/apachetest.tcl b/tests/apachetest/apachetest.tcl
index 38206ec..d9658c8 100644
--- a/tests/apachetest/apachetest.tcl
+++ b/tests/apachetest/apachetest.tcl
@@ -1,6 +1,6 @@
 # apachetest.tcl -- Tcl-based Apache test suite
 
-# Copyright 2001-2005 The Apache Software Foundation
+# Copyright 2001-2020 The Apache Tcl Team / The Apache Software Foundation
 
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# $Id$
-
 # This test suite provides a means to create configuration files, and
 # start apache with user-specified options.  All it needs to run is
 # the name of the Apache executable, which must, however, be compiled
@@ -43,16 +41,16 @@ proc kill {signal pid} {
     after 100
     set i 100
     while {1} {
-	catch {exec ps -p $pid} out
-	if {[regexp $pid $out]} {
-	    incr i 250
-	    after 250
-	} else {
-	    break
-	}
+        catch {exec ps -p $pid} out
+        if {[regexp $pid $out]} {
+            incr i 250
+            after 250
+        } else {
+            break
+        }
     }
     if {$i > 100} {
-	puts "Waiting [expr {$i/1000.0}] seconds until process was killed"
+        puts "Waiting [expr {$i/1000.0}] seconds until process was killed"
     }
 }
 
@@ -71,8 +69,7 @@ namespace eval apachetest {
 	} 
 	variable httpd_version  $::httpd_version
     # this file should be in the same directory this script is.
-    variable templatefile [file join [file dirname [info script]] \
-			       template.conf.2.tcl]
+    variable templatefile [file join [file dirname [info script]] template.conf.2.tcl]
 }
 
 # apachetest::need_modules --
@@ -94,7 +91,7 @@ namespace eval apachetest {
 proc apachetest::need_modules { modlist } {
     variable module_assoc
     foreach module_pair $modlist {
-	set module_assoc([lindex $module_pair 0]) [lindex $module_pair 1]
+        set module_assoc([lindex $module_pair 0]) [lindex $module_pair 1]
     }
 }
 
@@ -190,12 +187,12 @@ proc apachetest::startserver { args } {
 # getbinname - get the name of the apache binary, and check to make
 # sure it's ok.  The user should supply this parameter.
 
-proc apachetest::getbinname { argv } {
+proc apachetest::getbinname { bname } {
     variable binname
 
-    set binname [lindex $argv 0]
+    set binname $bname
     if { $binname == "" || ! [file executable $binname] } {
-	    error "Please supply the full name and path of the Apache executable on the command line."
+	    error "Invalid executable '$binname', please supply the full name and path of the Apache executable on the command line."
     }
     return $binname
 }
@@ -207,9 +204,15 @@ proc apachetest::getbinname { argv } {
 proc apachetest::getcompiledin { binname } {
     variable module_assoc
 
-    set bin [open [list | "$binname" -l] r]
-    set compiledin [read $bin]
-    close $bin
+    if {[catch {
+        set bin [open [list | "$binname" -l] r]
+        set compiledin [read $bin]
+        close $bin} e einfo]} {
+            puts "error: $e"
+            puts "error info: $einfo"
+
+            error "caught error in apachetest::getcompledin"
+    }
     set modlist [split $compiledin]
     set compiledin [list]
     set mod_so_present 0
@@ -234,16 +237,17 @@ proc apachetest::getcompiledin { binname } {
 proc apachetest::gethttpdconf { binname } {
     set bin [open [list | $binname -V] r]
     set options [read $bin]
-    close $bin
+    catch {close $bin}
     regexp {SERVER_CONFIG_FILE="(.*?)"} "$options" match filename
 
-    if { ! [file exists $filename] } {
+    if {![file exists $filename]} {
 
-# see if we can find something by combining HTTP_ROOT + SERVER_CONFIG_FILE
+        # see if we can find something by combining
+        # HTTP_ROOT + SERVER_CONFIG_FILE
 
         regexp {HTTPD_ROOT="(.*?)"} "$options" match httpdroot
         set completename [file join $httpdroot $filename]
-        if { ! [file exists $completename] } {
+        if {![file exists $completename]} {
             error "neither '$filename' or '$completename' exists"
         }
         return $completename
@@ -376,13 +380,15 @@ proc apachetest::determinemodules { binname } {
     }
     set needed [lsort $needed]
 
+    puts "needed: $needed"
+
     set needtoget [list]
     foreach mod $needed {
         if { [lsearch $compiledin $mod] == -1 } {
             lappend needtoget $mod
         }
     }
-    if { $needtoget == "" } {
+    if {$needtoget == ""} {
         return ""
     } else {
         return [getloadmodules $conffile $needtoget]
@@ -403,7 +409,7 @@ proc apachetest::determinemodules { binname } {
 # Results:
 #	None.
 
-proc apachetest::makeconf { outfile {extra ""} } {
+proc apachetest::makeconf { outfile bridge {extra ""} } {
     variable binname
     variable templatefile
     set CWD [pwd]
@@ -423,9 +429,19 @@ proc apachetest::makeconf { outfile {extra ""} } {
     puts "reading template from $templatefile"
     set fl [open [file join . $templatefile] r]
     set template [read $fl]
-    append template $extra
     close $fl
 
+# configure a specific bridge if -bridge passed as argument
+
+    if {$bridge == "default"} {
+        set bridge_conf "# Default bridge"
+    } else {
+        set bridge_conf "RivetServerConf MpmBridge $bridge"
+    }
+    set extra [string map [list BRIDGE $bridge_conf] $extra]
+
+    append template $extra
+
     puts $template
 
     set out [subst $template]
diff --git a/tests/apachetest/template.conf.2.tcl b/tests/apachetest/template.conf.2.tcl
index 96141ab..09679cf 100644
--- a/tests/apachetest/template.conf.2.tcl
+++ b/tests/apachetest/template.conf.2.tcl
@@ -1,4 +1,3 @@
-# \$Id: \$
 # Minimal config file for testing
 
 # Parsed by makeconf.tcl
diff --git a/tests/runtests.tcl b/tests/runtests.tcl
index eaa9ee0..8519a49 100755
--- a/tests/runtests.tcl
+++ b/tests/runtests.tcl
@@ -2,7 +2,7 @@
 # the next line restarts using tclsh \
 	exec tclsh "$0" "$@"
 
-# Copyright 2001-2005 The Apache Software Foundation
+# Copyright 2001-2020 The Apache Tcl Team / The Apache Software Foundation
 
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -19,7 +19,8 @@
 # $Id$
 
 set auto_path [linsert $auto_path 0 [file join [file dirname [info script]] apachetest]]
-
+set default_mpm prefork
+set httpd_args   {}
 puts stderr "runtests.tcl is running with auto_path: $auto_path"
 
 proc runtests_usage {} {
@@ -46,13 +47,53 @@ proc get_httpd_version {httpd {bd broken_down_version}} {
     return $m
 }
 
+# -- process_args
+#
+# basically this procedure strips from the argument list
+# the arguments not pertaining to the httpd server
+# Used to provide a way to control the test suite execution
+#
+
+proc process_args {arguments} {
+    global mpm
+    global bridge
+    global httpd_args
+
+    puts "n arguments: [llength $arguments]"
+    while {[llength $arguments]} {
+        set arguments [lassign $arguments a]
+        switch $a {
+            -mpm {
+                set arguments [lassign $arguments mpm]
+            }
+            -bridge {
+                set arguments [lassign $arguments bridge]
+            }
+            default {
+                lappend httpd_args $a
+            }
+        }
+    }
+}
+
 if { [llength $argv] < 1 } {
     runtests_usage
 } else {
-    set httpd_version [get_httpd_version [lindex $argv 0]]
+    set mpm $default_mpm
+    set bridge "default"
+
+    set httpd_bin     [lindex $argv 0]
+    set httpd_version [get_httpd_version $httpd_bin]
+    process_args      [lrange $argv 1 end]
+
+    puts "httpd_bin: $httpd_bin"
+    puts "httpd_args: $httpd_args"
+    puts "httpd_version: $httpd_version"
+    puts "mpm: $mpm, bridge: $bridge"
+
 }
 
-puts stderr "Tests will be run against apache ${httpd_version} version"
+puts stderr "Tests will be run against apache ${::httpd_version} version with the $mpm module and the $bridge bridge"
 
 package require apachetest
 
@@ -66,27 +107,28 @@ if { [encoding system] eq "utf-8" } {
 }
 
 if { [catch {
-    apachetest::getbinname $argv
+    apachetest::getbinname $httpd_bin
 } err ] } {
     puts stderr $err
     runtests_usage
 }
 
-apachetest::need_modules {
-    {mod_mime           mime_module}
-    {mod_negotiation    negotiation_module}
-    {mod_dir            dir_module}
-    {mod_log_config     log_config_module}
-    {mod_authz_core     authz_core_module}
-    {mod_authz_host     authz_host_module}
-    {mod_unixd          unixd_module}
-    {mod_mpm_prefork    mpm_prefork_module}
-}
+apachetest::need_modules [list \
+        {mod_mime                       mime_module} \
+        {mod_negotiation                negotiation_module} \
+        {mod_dir                        dir_module} \
+        {mod_log_config                 log_config_module} \
+        {mod_authz_core                 authz_core_module} \
+        {mod_authz_host                 authz_host_module} \
+        {mod_unixd                      unixd_module} \
+        [list mod_mpm_${mpm}            mpm_${mpm}_module]]
 
-apachetest::makeconf server.conf {
-    LoadModule rivet_module         [file join $CWD .. src/.libs mod_rivet[info sharedlibextension]]
-# User and Group directives removed to ease dependency of test suite from the output of command 'id' (from which
-# the values for these directives were inferred (Bug #53396)
+apachetest::makeconf server.conf $bridge {
+    LoadModule rivet_module [file join $CWD .. src/.libs mod_rivet[info sharedlibextension]]
+
+    # User and Group directives removed to ease dependency of test 
+    # suite from the output of command 'id' (from which
+    # the values for these directives were inferred (Bug #53396)
 
     <IfModule mod_mime.c>
         TypesConfig $CWD/mime.types
@@ -95,6 +137,7 @@ apachetest::makeconf server.conf {
         AddLanguage es .es
         AddType application/x-httpd-rivet .rvt
         AddType application/x-rivet-tcl   .tcl
+        BRIDGE
     </IfModule>
 
     <IfDefine SERVERCONFTEST>
@@ -124,14 +167,14 @@ set env(TCLLIBPATH) [file normalize [file join [file dirname [info script]] rive
 # If 'startserver' is specified on the command line, just start up the
 # server without running tests.
 
-puts "running test with arguments: $argv"
-switch -exact -- [lindex $argv 1] {
+puts "running test with arguments: $httpd_args"
+switch -exact -- [lindex $httpd_args 1] {
     startserver {
 	    apachetest::startserver
     }
     default {
-        set argv [lrange $argv 1 end]
-
+        #set argv [lrange $argv 1 end]
+        set argv $httpd_args
         source [file join . rivet.test]
     }
 }


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


[tcl-rivet] 04/07: add new entry in changelog

Posted by mx...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mxmanghi pushed a commit to branch quattuor
in repository https://gitbox.apache.org/repos/asf/tcl-rivet.git

commit e20401ca039b4ce884dce5fc4c692928f1de08a6
Author: Massimo Manghi <mx...@apache.org>
AuthorDate: Mon Sep 28 23:07:40 2020 +0200

    add new entry in changelog
---
 ChangeLog | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index dbe1590..1b81e09 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2020-09-28 Massimo Manghi <mx...@apache.org>
+    * src/mod_rivet_ng/TclWebapache.c: 
+    * src/mod_rivet_ng/TclWeb.c: 
+    * src/mod_rivet_ng/rivetCore.c: integrating development from uploadcmdfix
+
 2020-09-27 Massimo Manghi <mx...@apache.org>
 	* rivet/packages/formbroker/formbroker.tcl: add method form_exists to check for registration
 	of a form


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


[tcl-rivet] 05/07: add support for testing with different MPMs and bridges

Posted by mx...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mxmanghi pushed a commit to branch quattuor
in repository https://gitbox.apache.org/repos/asf/tcl-rivet.git

commit a522d75d070fcaaaf9fea6dd56397dd9148629ac
Author: Massimo Manghi <mx...@apache.org>
AuthorDate: Sun Sep 27 23:52:14 2020 +0200

    add support for testing with different MPMs and bridges
---
 tests/runtests.tcl | 2 --
 1 file changed, 2 deletions(-)

diff --git a/tests/runtests.tcl b/tests/runtests.tcl
index 8519a49..da4e069 100755
--- a/tests/runtests.tcl
+++ b/tests/runtests.tcl
@@ -16,8 +16,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# $Id$
-
 set auto_path [linsert $auto_path 0 [file join [file dirname [info script]] apachetest]]
 set default_mpm prefork
 set httpd_args   {}


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


[tcl-rivet] 03/07: add add method form_exists to check for registration of a form

Posted by mx...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mxmanghi pushed a commit to branch quattuor
in repository https://gitbox.apache.org/repos/asf/tcl-rivet.git

commit 718a526105d582d06bb313a2288a1f0e09f7a150
Author: Massimo Manghi <mx...@apache.org>
AuthorDate: Sun Sep 27 23:41:18 2020 +0200

    add add method form_exists to check for registration of a form
---
 rivet/packages/formbroker/formbroker.tcl | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/rivet/packages/formbroker/formbroker.tcl b/rivet/packages/formbroker/formbroker.tcl
index 37ff92a..3edca9b 100644
--- a/rivet/packages/formbroker/formbroker.tcl
+++ b/rivet/packages/formbroker/formbroker.tcl
@@ -788,6 +788,12 @@ namespace eval FormBroker {
         return [namespace current]::$form_name 
     }
 
+    proc form_exists {form_cmd} {
+        variable form_definitions
+
+        return [dict exists $form_definitions [namespace tail $form_cmd]]
+    }
+
     proc creategc {varname args} {
         set formv [uplevel [list set $varname [::FormBroker::create {*}$args]]]
         uplevel [list trace add variable $varname unset \
@@ -800,4 +806,4 @@ namespace eval FormBroker {
     namespace ensemble create
 }
 
-package provide formbroker 1.0
+package provide formbroker 1.0.1


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


[tcl-rivet] 02/07: restructuring and testing new code of upload command

Posted by mx...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mxmanghi pushed a commit to branch quattuor
in repository https://gitbox.apache.org/repos/asf/tcl-rivet.git

commit a918f36b1d5ac12b1f859a0e60951011eac6cc44
Author: Massimo Manghi <mx...@apache.org>
AuthorDate: Sat May 2 02:01:22 2020 +0200

    restructuring and testing new code of upload command
---
 src/TclWeb.h                    |  37 ++++----
 src/mod_rivet_ng/TclWebapache.c | 150 ++++++++++++++++++--------------
 src/mod_rivet_ng/rivetCore.c    | 183 ++++++++++++++++++++--------------------
 3 files changed, 199 insertions(+), 171 deletions(-)

diff --git a/src/TclWeb.h b/src/TclWeb.h
index dffec44..0de1ba9 100644
--- a/src/TclWeb.h
+++ b/src/TclWeb.h
@@ -158,17 +158,17 @@ int TclWeb_PrepareUpload(char *varname, TclWebRequest *req);
  *
  * TclWeb_UploadChannel --
  *
- * Takes the address of a Tcl_Channel and uses it to create a channel
- * pointing to the upload data.
+ * It opens a new channel and sets its translation and encoding as binary
+ * The channel name is retuned as result in the interpreter pointed by req->interp
  *
  * Results:
  *
- * 'chan' points to a FileChannel containing the uploaded data.
+ * Makes the channel name available to the script level
  *
  *-----------------------------------------------------------------------------
  */
 
-int TclWeb_UploadChannel(char *varname, Tcl_Channel *chan, TclWebRequest *req);
+int TclWeb_UploadChannel(char *varname, TclWebRequest *req);
 
 /*
  *-----------------------------------------------------------------------------
@@ -187,68 +187,71 @@ int TclWeb_UploadSave(char *varname, Tcl_Obj *filename, TclWebRequest *req);
  *
  * TclWeb_UploadData --
  *
- * Fills in the 'data' Tcl_Obj with the uploaded data.
+ * Returns the uploaded data to the Tcl script level.
+ * 
+ * If the config parameter upload_files_to_var is not set the procedure
+ * returs an error
  *
  *-----------------------------------------------------------------------------
  */
 
-int TclWeb_UploadData(char *varname, Tcl_Obj *data, TclWebRequest *req);
+int TclWeb_UploadData(char *varname, TclWebRequest *req);
 
 /*
  *-----------------------------------------------------------------------------
  *
  * TclWeb_UploadSize --
  *
- * Stores, in 'sz' the size of the data uploaded.
+ * Returns the size of the data uploaded.
  *
  *-----------------------------------------------------------------------------
  */
 
-int TclWeb_UploadSize(Tcl_Obj *sz, TclWebRequest *req);
+int TclWeb_UploadSize(TclWebRequest *req);
 
 /*
  *-----------------------------------------------------------------------------
  *
  * TclWeb_UploadType --
  *
- * Stores, in 'type' the mime type of the file uploaded.
+ * Returns the mime type of the file uploaded.
  *
  *-----------------------------------------------------------------------------
  */
 
-int TclWeb_UploadType(Tcl_Obj *type, TclWebRequest *req);
+int TclWeb_UploadType(TclWebRequest *req);
 
 /*
  *-----------------------------------------------------------------------------
  *
  * TclWeb_UploadFilename --
  *
- * Get the original filename of the uploaded data, on the client side.
+ * Returns the original filename of the uploaded data, on the client side.
  *
  * Results:
  *
- * Stores the filename in 'filename'.
+ * Returns the filename to the script level
  *
  *-----------------------------------------------------------------------------
  */
 
-int TclWeb_UploadFilename(Tcl_Obj *filename, TclWebRequest *req);
+int TclWeb_UploadFilename(TclWebRequest *req);
 
 /*
  *-----------------------------------------------------------------------------
  *
  * TclWeb_UploadTempname --
  *
- * Get the name of the temp file the uploaded data was stored in.
+ * Returns the name of the temp file the uploaded data was stored in.
  *
  * Results:
  *
- * Stores the temp name in 'tempname'.
+ * the 'tempname' is returned to the script level
  *
  *-----------------------------------------------------------------------------
  */
 
-int TclWeb_UploadTempname(Tcl_Obj *tempname, TclWebRequest *req);
+int TclWeb_UploadTempname(TclWebRequest *req);
 
 /*
  *-----------------------------------------------------------------------------
@@ -264,7 +267,7 @@ int TclWeb_UploadTempname(Tcl_Obj *tempname, TclWebRequest *req);
  *-----------------------------------------------------------------------------
  */
 
-int TclWeb_UploadNames(Tcl_Obj *names, TclWebRequest *req);
+int TclWeb_UploadNames(TclWebRequest *req);
 
 int TclWeb_Escape(char *out, char *in, int len, void *var);
 
diff --git a/src/mod_rivet_ng/TclWebapache.c b/src/mod_rivet_ng/TclWebapache.c
index d755507..9d573ee 100644
--- a/src/mod_rivet_ng/TclWebapache.c
+++ b/src/mod_rivet_ng/TclWebapache.c
@@ -314,7 +314,7 @@ TclWeb_GetVar(Tcl_Obj *result, char *varname, int source, TclWebRequest *req)
 
     if (result->length == 0)
     {
-	return TCL_ERROR;
+	    return TCL_ERROR;
     }
 
     return TCL_OK;
@@ -334,19 +334,19 @@ TclWeb_GetVarAsList(Tcl_Obj *result, char *varname, int source, TclWebRequest *r
     while (i < j)
     {
 
-	if (!strncmp(varname, TclWeb_StringToUtf(parms[i].key, req),
-		     strlen(varname) < strlen(parms[i].key) ?
-		     strlen(parms[i].key) : strlen(varname)))
-	{
-	    Tcl_ListObjAppendElement(req->interp, result,
-				     TclWeb_StringToUtfToObj(parms[i].val, req));
-	}
-	i++;
+        if (!strncmp(varname, TclWeb_StringToUtf(parms[i].key, req),
+                 strlen(varname) < strlen(parms[i].key) ?
+                 strlen(parms[i].key) : strlen(varname)))
+        {
+            Tcl_ListObjAppendElement(req->interp, result,
+                         TclWeb_StringToUtfToObj(parms[i].val, req));
+        }
+        i++;
     }
 
     if (result == NULL)
     {
-	return TCL_ERROR;
+        return TCL_ERROR;
     }
     return TCL_OK;
 }
@@ -660,47 +660,59 @@ int TclWeb_PrepareUpload(char *varname, TclWebRequest *req)
     }
 }
 
-int TclWeb_UploadChannel(char *varname, Tcl_Channel *chan, TclWebRequest *req)
+int TclWeb_UploadChannel(char *varname, TclWebRequest *req)
 {
-    *chan = Tcl_OpenFileChannel (req->interp, req->upload->tempname, "r", 0);
+    Tcl_Channel chan;
+
+    chan = Tcl_OpenFileChannel(req->interp, req->upload->tempname, "r", 0);
+
     if (chan == NULL) {
-	return TCL_ERROR;
-    } else {
-	if (Tcl_SetChannelOption(req->interp, *chan,
-			         "-translation", "binary") == TCL_ERROR) {
-	    return TCL_ERROR;
-	}
-	if (Tcl_SetChannelOption(req->interp, *chan,
-				 "-encoding", "binary") == TCL_ERROR) {
 	    return TCL_ERROR;
-	}
-	Tcl_RegisterChannel (req->interp, *chan);
-	return TCL_OK;
+    } else {
+        Tcl_Obj* result;
+
+        if (Tcl_SetChannelOption(req->interp,chan,"-translation","binary") == TCL_ERROR) {
+            return TCL_ERROR;
+        }
+        if (Tcl_SetChannelOption(req->interp,chan,"-encoding","binary") == TCL_ERROR) {
+            return TCL_ERROR;
+        }
+        Tcl_RegisterChannel(req->interp,chan);
+
+        result = Tcl_NewObj();        
+        Tcl_SetStringObj(result, Tcl_GetChannelName(chan), -1);
+        Tcl_SetObjResult(req->interp, result);
+        
+        return TCL_OK;
     }
 }
 
-int TclWeb_UploadTempname(Tcl_Obj *tempname, TclWebRequest *req)
+int TclWeb_UploadTempname(TclWebRequest *req)
 {
-    Tcl_SetStringObj(tempname,
-		     TclWeb_StringToUtf(req->upload->tempname,
-					req), -1);
+    Tcl_Obj *tempname = Tcl_NewObj();
+
+    Tcl_SetStringObj(tempname,TclWeb_StringToUtf(req->upload->tempname,req), -1);
+    Tcl_SetObjResult(req->interp, tempname);
+
     return TCL_OK;
 }
 
 
 int TclWeb_UploadSave(char *varname, Tcl_Obj *filename, TclWebRequest *req)
 {
-	apr_status_t	status;
+	apr_status_t status;
+
 	status = apr_file_copy(req->upload->tempname ,Tcl_GetString(filename),APR_FILE_SOURCE_PERMS,req->req->pool);
-	if ( status == 0 ) {
+	if (status == APR_SUCCESS) {
 	    return TCL_OK;
 	} else {
 		return TCL_ERROR;
 	}
 }
 
-int TclWeb_UploadData(char *varname, Tcl_Obj *data, TclWebRequest *req)
+int TclWeb_UploadData(char *varname, TclWebRequest *req)
 {
+    Tcl_Obj* result;
     rivet_server_conf *rsc = NULL;
 
     rsc  = RIVET_SERVER_CONF( req->req->server->module_config );
@@ -708,68 +720,80 @@ int TclWeb_UploadData(char *varname, Tcl_Obj *data, TclWebRequest *req)
        get everything fixed and working first */
     if (rsc->upload_files_to_var)
     {
-	Tcl_Channel chan;
-	chan = Tcl_OpenFileChannel (req->interp, req->upload->tempname, "r", 0);
-	if (chan == NULL) {
-	    return TCL_ERROR;
-	}
-	if (Tcl_SetChannelOption(req->interp, chan,
-				 "-translation", "binary") == TCL_ERROR) {
-	    return TCL_ERROR;
-	}
-	if (Tcl_SetChannelOption(req->interp, chan,
-				 "-encoding", "binary") == TCL_ERROR) {
-	    return TCL_ERROR;
-	}
+        Tcl_Channel chan;
+        
+        chan = Tcl_OpenFileChannel (req->interp, req->upload->tempname, "r", 0);
+        if (chan == NULL) {
+            return TCL_ERROR;
+        }
+        if (Tcl_SetChannelOption(req->interp, chan,
+                     "-translation", "binary") == TCL_ERROR) {
+            return TCL_ERROR;
+        }
+        if (Tcl_SetChannelOption(req->interp, chan,
+                     "-encoding", "binary") == TCL_ERROR) {
+            return TCL_ERROR;
+        }
 
-	/* Put data in a variable  */
-	Tcl_ReadChars(chan, data, (int)ApacheUpload_size(req->upload), 0);
-	if (Tcl_Close(req->interp, chan) == TCL_ERROR) {
-	    return TCL_ERROR;
-	}
+        /* Put data in a variable  */
+        result = Tcl_NewObj();
+        Tcl_ReadChars(chan, result, (int)ApacheUpload_size(req->upload), 0);
+        if (Tcl_Close(req->interp, chan) == TCL_ERROR) {
+            return TCL_ERROR;
+        }
+        
+        Tcl_SetObjResult(req->interp, result);
     } else {
-	Tcl_AppendResult(req->interp,
-			 "RivetServerConf UploadFilesToVar is not set", NULL);
-	return TCL_ERROR;
+        Tcl_AppendResult(req->interp,
+                 "RivetServerConf UploadFilesToVar is not set", NULL);
+        return TCL_ERROR;
     }
+    
     return TCL_OK;
 }
 
-int TclWeb_UploadSize(Tcl_Obj *sz, TclWebRequest *req)
+int TclWeb_UploadSize(TclWebRequest *req)
 {
-    Tcl_SetIntObj(sz, (int)ApacheUpload_size(req->upload));
+    Tcl_Obj* result = Tcl_NewObj();
+    Tcl_SetIntObj(result, (int)ApacheUpload_size(req->upload));
+    Tcl_SetObjResult(req->interp, result);
     return TCL_OK;
 }
 
-int TclWeb_UploadType(Tcl_Obj *type, TclWebRequest *req)
+int TclWeb_UploadType(TclWebRequest *req)
 {
+    Tcl_Obj *type = Tcl_NewObj();
+
     /* If there is a type, return it, if not, return blank. */
     Tcl_SetStringObj(type, ApacheUpload_type(req->upload)
 		     ? (char *)ApacheUpload_type(req->upload) : (char *)"", -1);
+
+    Tcl_SetObjResult(req->interp, type);
     return TCL_OK;
 }
 
-int TclWeb_UploadFilename(Tcl_Obj *filename, TclWebRequest *req)
+int TclWeb_UploadFilename(TclWebRequest *req)
 {
-    Tcl_SetStringObj(filename,
-		     TclWeb_StringToUtf(req->upload->filename,
-					req), -1);
+    Tcl_Obj *filename = Tcl_NewObj();
+    Tcl_SetStringObj(filename,TclWeb_StringToUtf(req->upload->filename,req), -1);
+
+    Tcl_SetObjResult(req->interp, filename);
     return TCL_OK;
 }
 
-int TclWeb_UploadNames(Tcl_Obj *names, TclWebRequest *req)
+int TclWeb_UploadNames(TclWebRequest *req)
 {
     ApacheUpload *upload;
+    Tcl_Obj      *names = Tcl_NewObj();
 
     upload = ApacheRequest_upload(req->apachereq);
     while (upload)
     {
-	Tcl_ListObjAppendElement(
-	    req->interp, names,
-	    TclWeb_StringToUtfToObj(upload->name,req));
-	upload = upload->next;
+        Tcl_ListObjAppendElement(req->interp,names,TclWeb_StringToUtfToObj(upload->name,req));
+        upload = upload->next;
     }
 
+    Tcl_SetObjResult(req->interp,names);
     return TCL_OK;
 }
 
diff --git a/src/mod_rivet_ng/rivetCore.c b/src/mod_rivet_ng/rivetCore.c
index 0679bff..5dc9a1b 100644
--- a/src/mod_rivet_ng/rivetCore.c
+++ b/src/mod_rivet_ng/rivetCore.c
@@ -1017,22 +1017,12 @@ TCL_CMD_HEADER( Rivet_ApacheTable )
     return TCL_OK;
 }
 
-
 /*
  *-----------------------------------------------------------------------------
  *
  * Rivet_Upload --
  *
- *      Deals with file uploads (multipart/form-data) like so:
- *
- *      upload channel uploadname
- *      upload save name uploadname
- *      upload data uploadname
- *      upload exists uploadname
- *      upload size uploadname
- *      upload type uploadname
- *      upload filename uploadname
- *      upload names
+ *      Deals with file uploads (multipart/form-data):
  *
  * Results:
  *      A standard Tcl result.
@@ -1049,7 +1039,29 @@ TCL_CMD_HEADER( Rivet_Upload )
     char*   varname = NULL;
     int     subcommandindex;
 
-    Tcl_Obj* result = NULL;
+    /* ::rivet::upload subcommands must register
+     *
+     * - subcommand definition
+     * - subcommand integer progressive index
+     * - subcommand required (minimum) number of arguments
+     *
+     * +----------------------------------------+-------+
+     * |         argv[1]    argv[2]   argv[3]   | argc  |
+     * +----------------------------------------+-------+
+     * |  upload channel   uploadname           |   3   |
+     * |  upload save      uploadname filename  |   4   |
+     * |  upload data      uploadname           |   3   |
+     * |  upload exists    uploadname           |   3   |
+     * |  upload size      uploadname           |   3   |
+     * |  upload type      uploadname           |   3   |
+     * |  upload filename  uploadname           |   3   |
+     * |  upload tempname  uploadname           |   3   |
+     * |  upload names                          |   2   |
+     * +----------------------------------------+-------+
+     *
+     * a subcommand first optional argument must be the name
+     * of an upload
+     */
 
     static CONST84 char *SubCommand[] = {
         "channel",
@@ -1076,115 +1088,104 @@ TCL_CMD_HEADER( Rivet_Upload )
         NAMES
     };
 
-    rivet_thread_private*   private;
+    static CONST84 int cmds_objc[] = { 3,4,3,3,3,3,3,3,2 };
+    int expected_objc;
+
+    rivet_thread_private* private;
 
     THREAD_PRIVATE_DATA(private)
     CHECK_REQUEST_REC(private,"::rivet::upload")
     if (Tcl_GetIndexFromObj(interp, objv[1], SubCommand,
-                        "channel|save|data|exists|size|type|filename|names|tempname"
-                        "|tempname|names",
+                        "channel|save|data|exists|size|type|filename|tempname|names",
                         0, &subcommandindex) == TCL_ERROR) {
         return TCL_ERROR;
     }
 
-    /* If it's any of these, we need to find a specific name. */
+    expected_objc = cmds_objc[subcommandindex];
 
-    /* Excluded case is NAMES. */
+    if (objc != expected_objc) {
+        Tcl_Obj* infoobj = Tcl_NewStringObj("Wrong argument numbers: ",-1);
 
-    if ((enum subcommand)subcommandindex == CHANNEL     ||
-        (enum subcommand)subcommandindex == SAVE        ||
-        (enum subcommand)subcommandindex == DATA        ||
-        (enum subcommand)subcommandindex == EXISTS      ||
-        (enum subcommand)subcommandindex == SIZE        ||
-        (enum subcommand)subcommandindex == TYPE        ||
-        (enum subcommand)subcommandindex == FILENAME    ||
-        (enum subcommand)subcommandindex == TEMPNAME)
-    {
+        Tcl_IncrRefCount(infoobj);
+        Tcl_AppendObjToObj(infoobj,Tcl_NewIntObj(expected_objc));
+        Tcl_AppendStringsToObj(infoobj," arguments expected");
+        Tcl_AppendObjToErrorInfo(interp, infoobj);
+        Tcl_DecrRefCount(infoobj);
+
+        if (subcommandindex == SAVE) {
+            Tcl_WrongNumArgs(interp, 2, objv, "uploadname filename");
+        } else {
+            Tcl_WrongNumArgs(interp, objc, objv, "uploadname");
+        }
+        return TCL_ERROR;
+    }
+
+    /* We check whether an upload with a given name exists */
+
+    if (objc >= 3) {
+        int tcl_status;
         varname = Tcl_GetString(objv[2]);
-        if ((enum subcommand)subcommandindex != EXISTS)
-        {
-            if (TclWeb_PrepareUpload(varname, private->req) != TCL_OK)
-            {
-                Tcl_AddErrorInfo(interp, "Unable to find variable");
-                return TCL_ERROR;
-            }
+
+        /* TclWeb_PrepareUpload calls ApacheUpload_find and returns
+         * TCL_OK if the named upload exists in the current request */
+        tcl_status = TclWeb_PrepareUpload(varname, private->req);
+
+        if (subcommandindex == EXISTS) {
+            Tcl_Obj* result = NULL;
+            int upload_prepared = 0;
+
+            if (tcl_status == TCL_OK) upload_prepared = 1;
+
+            result = Tcl_NewObj();
+            Tcl_SetIntObj(result,upload_prepared);
+            Tcl_SetObjResult(interp, result);
+            return TCL_OK;
+                
         }
 
-        /* If it's not the 'save' command, then it has to have an objc
-           of 3. */
-        if ((enum subcommand)subcommandindex != SAVE && objc != 3)
+        if (tcl_status != TCL_OK)
         {
-            Tcl_WrongNumArgs(interp, 2, objv, "varname");
+            Tcl_AddErrorInfo(interp, "Unable to find the upload named '");
+            Tcl_AppendObjToErrorInfo(interp,Tcl_NewStringObj(varname,-1));
+            Tcl_AppendObjToErrorInfo(interp,Tcl_NewStringObj("'",-1));
             return TCL_ERROR;
         }
     }
 
-    result = Tcl_NewObj();
+    /* CHANNEL  : get the upload channel name
+     * SAVE     : save data to a specified filename
+     * DATA     : get the uploaded data into a Tcl variable
+     * SIZE     : uploaded data size
+     * TYPE     : upload mimetype
+     * FILENAME : upload original filename
+     * TEMPNAME : temporary file where the upload is taking place
+     * NAMES    : list of uploads
+     *
+     * the procedure shouldn't reach for the default case
+     */
 
     switch ((enum subcommand)subcommandindex)
     {
-        case CHANNEL: {
-            Tcl_Channel chan;
-            char *channelname = NULL;
-
-            if (TclWeb_UploadChannel(varname, &chan, private->req) != TCL_OK) {
-                return TCL_ERROR;
-            }
-            channelname = (char *)Tcl_GetChannelName(chan);
-            Tcl_SetStringObj(result, channelname, -1);
-            break;
-        }
+        case CHANNEL:
+            return TclWeb_UploadChannel(varname, private->req);
         case SAVE:
-            /* save data to a specified filename  */
-            if (objc != 4) {
-                Tcl_WrongNumArgs(interp, 2, objv, "uploadname filename");
-                return TCL_ERROR;
-            }
-
-            if (TclWeb_UploadSave(varname, objv[3], private->req) != TCL_OK)
-            {
-                return TCL_ERROR;
-            }
-            break;
+            return TclWeb_UploadSave(varname, objv[3], private->req);
         case DATA:
-            if (TclWeb_UploadData(varname, result, private->req) != TCL_OK) {
-                return TCL_ERROR;
-            }
-            break;
-        case EXISTS:
-            if (TclWeb_PrepareUpload(varname, private->req) != TCL_OK)
-            {
-                Tcl_SetIntObj(result, 0);
-            } else {
-                Tcl_SetIntObj(result, 1);
-            }
-            break;
+            return TclWeb_UploadData(varname, private->req);
         case SIZE:
-            TclWeb_UploadSize(result, private->req);
-            break;
+            return TclWeb_UploadSize(private->req);
         case TYPE:
-            TclWeb_UploadType(result, private->req);
-            break;
+            return TclWeb_UploadType(private->req);
         case FILENAME:
-            TclWeb_UploadFilename(result, private->req);
-            break;
+            return TclWeb_UploadFilename(private->req);
         case TEMPNAME:
-            TclWeb_UploadTempname(result,private->req);
-            break;
+            return TclWeb_UploadTempname(private->req);
         case NAMES:
-            if (objc != 2)
-            {
-                Tcl_WrongNumArgs(interp, 1, objv, "names");
-                return TCL_ERROR;
-            }
-            TclWeb_UploadNames(result, private->req);
-            break;
+            return TclWeb_UploadNames(private->req);
         default:
-            Tcl_WrongNumArgs(interp, 1, objv,
-                             "channel|save ?name?|data|exists|size|type|filename|names|tempname");
+            Tcl_WrongNumArgs(interp, 1, objv,"Rivet internal error: inconsistent argument");
     }
-    Tcl_SetObjResult(interp, result);
-    return TCL_OK;
+    return TCL_ERROR;
 }
 
 /*


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


[tcl-rivet] 07/07: merging master into quattuor, reorganizing internal database and adding new debugging function

Posted by mx...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mxmanghi pushed a commit to branch quattuor
in repository https://gitbox.apache.org/repos/asf/tcl-rivet.git

commit 395b4129a2c9b765a3e92b80f0fa066a2d0aaa89
Author: Massimo Manghi <mx...@apache.org>
AuthorDate: Fri Oct 2 01:32:55 2020 +0200

    merging master into quattuor, reorganizing internal database and adding new debugging function
---
 ChangeLog                                |  28 +++++-
 configure.ac                             |  28 +++++-
 doc/xml/directives.xml                   | 103 +++++++++++---------
 src/mod_rivet_ng/apache_config.c         |  37 ++++----
 src/mod_rivet_ng/mod_rivet.c             | 127 ++++++++++++++-----------
 src/mod_rivet_ng/mod_rivet.h             | 126 ++++++++++++++-----------
 src/mod_rivet_ng/mod_rivet_cache.c       |  76 ++++++++++++---
 src/mod_rivet_ng/mod_rivet_cache.h       |   6 +-
 src/mod_rivet_ng/mod_rivet_common.c      | 100 ++++++++++----------
 src/mod_rivet_ng/mod_rivet_common.h      |   4 +-
 src/mod_rivet_ng/rivetCore.c             | 155 +++++++++++++++++++++++++------
 src/mod_rivet_ng/rivetInspect.c          |  12 +--
 src/mod_rivet_ng/rivet_lazy_mpm.c        | 101 ++++++++++----------
 src/mod_rivet_ng/rivet_prefork_mpm.c     |  44 +++++++--
 src/mod_rivet_ng/rivet_worker_mpm.c      |  10 +-
 src/mod_rivet_ng/worker_prefork_common.c |  13 +--
 src/rivet.h                              |   4 +-
 17 files changed, 626 insertions(+), 348 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 1b81e09..bbaa408 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,29 @@
+2020-10-01 Massimo Manghi <mx...@apache.org>
+	* src/mod_rivet_ng/rivet_prefork_mpm.c: Fixed trivial bug in checking the
+	rivet cache size
+	* configure.ac: add macro to define preprocessor symbol	RIVET_DEBUG_CODE
+
+2020-09-29 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 also rivet_server_init
+	out of the server configuration and into the module_globals
+
 2020-09-28 Massimo Manghi <mx...@apache.org>
-    * src/mod_rivet_ng/TclWebapache.c: 
-    * src/mod_rivet_ng/TclWeb.c: 
-    * src/mod_rivet_ng/rivetCore.c: integrating development from uploadcmdfix
+	* src/mod_rivet_ng/TclWebapache.c: 
+	* src/mod_rivet_ng/TclWeb.c: 
+	* src/mod_rivet_ng/rivetCore.c: integrating development from uploadcmdfix
+	* 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
diff --git a/configure.ac b/configure.ac
index 1f5c279..43a9885 100644
--- a/configure.ac
+++ b/configure.ac
@@ -6,8 +6,6 @@ dnl
 dnl You need at least autoconf 2.59
 dnl
 #
-# RCS: @(#) $Id$
-
 #-----------------------------------------------------------------------
 # Sample configure.in for Tcl Extensions.  The only places you should
 # need to modify this file are marked by the string __CHANGE__
@@ -573,7 +571,6 @@ AC_DEFUN([RIVET_TCL_LIB],[
     AC_MSG_RESULT([$with_rivet_target_dir])
 ])
 
-
 # DISPLAY_RIVET_VERSION
 #
 # --enable-version-display=[yes|no] (default: no)
@@ -700,6 +697,30 @@ AC_DEFUN([HTTP_REQUESTS_MUTEX],[
     fi
 ])
 
+# -- RIVET_DEBUG_BUILD
+#
+# Defining a symbol for conditional inclusion of code for debugging purposes
+#
+# Default: no
+#
+
+AC_DEFUN([BUILD_DEBUG_CODE],[
+    AC_ARG_ENABLE(
+        rivet_debug_build,
+        [  --enable-rivet-debug-build Includes optional debugging code],
+        [ rivet_debug_build=$enable_rivet_debug_build ],
+        [ rivet_debug_build="no" ]
+    )
+
+    AC_MSG_CHECKING([if we are building mod_rivet for debugging])
+    if test "$rivet_debug_build" = "yes"; then
+        AC_MSG_RESULT([yes])
+        AC_DEFINE(DEBUG_BUILD,1,[we are building mod_rivet with optional code])
+    else
+        AC_MSG_RESULT([no, ordinary build])
+    fi
+])
+
 # RIVET_COMMANDS_EXPORT (--enable-rivet-commands-export).
 # Enable export of commands in Rivet's namespace. Definining this symbols
 # sets the boolean configuration variable rivet_commands_export 
@@ -836,6 +857,7 @@ RIVET_CORE_CMDS
 RIVET_CHANNEL
 SINGLE_WORKER_TCL_THREAD
 HTTP_REQUESTS_MUTEX
+BUILD_DEBUG_CODE
 AC_HEADER_STDBOOL
 
 # Let's separate the point version from the major and minor version
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 467d47d..5f6fa23 100644
--- a/src/mod_rivet_ng/apache_config.c
+++ b/src/mod_rivet_ng/apache_config.c
@@ -1,6 +1,7 @@
 /* apache_config.c -- configuration functions for apache 2.x */
 
-/* Copyright 2000-2005 The Apache Software Foundation
+/* 
+   Copyright 2002-2020 The Apache Tcl Team
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
@@ -15,8 +16,6 @@
    limitations under the License.
 */
 
-/* $Id$ */
-
 /* Rivet config */
 #ifdef HAVE_CONFIG_H
 #include <rivet_config.h>
@@ -224,12 +223,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;
@@ -237,7 +236,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;
 }
 
@@ -407,14 +406,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;
     
@@ -466,15 +465,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 );
@@ -645,15 +644,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/mod_rivet.c b/src/mod_rivet_ng/mod_rivet.c
index c67dd63..e3a114b 100644
--- a/src/mod_rivet_ng/mod_rivet.c
+++ b/src/mod_rivet_ng/mod_rivet.c
@@ -101,15 +101,13 @@ DLLEXPORT module		        rivet_module;
 */
 
 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 );
-
     /* With the env variable RIVET_MPM_BRIDGE we have the chance to tell mod_rivet 
        what bridge custom implementation we want to be loaded */
 
@@ -120,24 +118,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);   
         }
 
@@ -169,60 +167,56 @@ Rivet_SeekMPMBridge (apr_pool_t* pool,server_rec* server)
             mpm_bridge_path = apr_pstrdup(pool,mpm_worker_bridge);
         }
         mpm_bridge_path = apr_pstrcat(pool,RIVET_DIR,"/mpm/",mpm_bridge_path,NULL);
+
     }
     return mpm_bridge_path;
 }
 
 /* 
-* -- Rivet_CreateModuleGlobals
-*
-* module globals (mod_rivet_globals) allocation and initialization
-* 
-*/
+ * -- Rivet_CreateModuleGlobals
+ *
+ * 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);
     }
 
-    /* This mutex should protect the process wide pool */
-
-    //apr_thread_mutex_create(&mod_rivet_g->pool_mutex, APR_THREAD_MUTEX_UNNESTED, pool);
-
-    /* establishing the name of the bridge to be loaded */
-
-    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);
     }
 
-    mod_rivet_g->server = server;
-
     return mod_rivet_g;
 }
 
 /*
-* -- Rivet_Exit_Handler
-*
-* 
-*
-*/
+ * -- Rivet_Exit_Handler
+ *
+ * 
+ *
+ */
 
 int Rivet_Exit_Handler(int code)
 {
@@ -322,9 +316,9 @@ Rivet_RunServerInit (apr_pool_t *pPool, apr_pool_t *pLog, apr_pool_t *pTemp, ser
              * created an interpreter so far we create one
              */
 
-            if ((interp_obj == NULL) || vhost_rsc->separate_virtual_interps) 
+            if ((interp_obj == NULL) || module_globals->separate_virtual_interps) 
             {
-                interp_obj = Rivet_NewVHostInterp(private,s);
+                interp_obj = Rivet_NewVHostInterp(private,vhost_rsc->default_cache_size);
 
                 /* We initialize the interpreter and we won't 
                  * register a channel with it because
@@ -407,16 +401,22 @@ Rivet_ServerInit (apr_pool_t *pPool, apr_pool_t *pLog, apr_pool_t *pTemp, server
 		apr_pool_userdata_set((const void *)1, userdata_key,
                               apr_pool_cleanup_null, server->process->pool);
 
-        ap_log_error(APLOG_MARK,APLOG_INFO,0,server,
+        ap_log_error(APLOG_MARK,APLOG_DEBUG,0,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 structure 
-     * is allocated and the MPM bridge name is established */
+    /* 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 */
 
@@ -425,7 +425,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");
@@ -448,7 +448,7 @@ Rivet_ServerInit (apr_pool_t *pPool, apr_pool_t *pLog, apr_pool_t *pTemp, server
         ap_assert(RIVET_MPM_BRIDGE_FUNCTION(request_processor) != NULL);
         ap_assert(RIVET_MPM_BRIDGE_FUNCTION(thread_interp) != NULL);
 
-        //apr_thread_mutex_create(&module_globals->pool_mutex, APR_THREAD_MUTEX_UNNESTED, pPool);
+        apr_thread_mutex_create(&module_globals->pool_mutex, APR_THREAD_MUTEX_UNNESTED, pPool);
 
     }
     else
@@ -488,8 +488,12 @@ static void Rivet_ChildInit (apr_pool_t *pChild, server_rec *server)
     rivet_server_conf*  root_server_conf;
     server_rec*         s;
 
-    /* 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 
+    /* the thread key used to access to Tcl threads private data */
+
+    ap_assert (apr_threadkey_private_create (&rivet_thread_key, NULL, pChild) == APR_SUCCESS);
+
+    /* 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
@@ -500,13 +504,24 @@ static void Rivet_ChildInit (apr_pool_t *pChild, server_rec *server)
     Tcl_InitNotifier();
 #endif
 
-    /* for any non-prefork bridge the module globals are to be created here */
+    /* 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 
+     * different threads
+     */
+
+    apr_thread_mutex_create(&module_globals->pool_mutex, APR_THREAD_MUTEX_UNNESTED, pChild);
+
     /* Once we have established a pool with the same lifetime of the child process we
      * process all the configured server records assigning an integer as unique key 
      * to each of them 
@@ -524,11 +539,10 @@ static void Rivet_ChildInit (apr_pool_t *pChild, server_rec *server)
          * was called. We really need a separate one for each server,
          * so we go ahead and create one here, if necessary. */
 
-        if (s != server && myrsc == root_server_conf) 
-        {
+        if (s != server && myrsc == root_server_conf) {
             myrsc = RIVET_NEW_CONF(pChild);
             ap_set_module_config(s->module_config, &rivet_module, myrsc);
-            Rivet_CopyConfig(root_server_conf,myrsc);
+            Rivet_CopyConfig( root_server_conf, myrsc );
         }
 
         myrsc->idx = idx++;
@@ -553,6 +567,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.
  *
@@ -561,6 +583,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 04de062..2dbcf2a 100644
--- a/src/mod_rivet_ng/mod_rivet.h
+++ b/src/mod_rivet_ng/mod_rivet.h
@@ -35,17 +35,15 @@
 #include <rivet_config.h>
 #endif
 
-#include "rivet_types.h"
-
 /*
  * Petasis 16 Dec 2018: This causes the symbol to be exported also from MPMs...
-
-  APLOG_USE_MODULE(rivet);
-
-  PLEASE: do not use any of APLOG_USE_MODULE, AP_DECLARE_MODULE,
-  AP_MODULE_DECLARE_DATA in this header file!
- 
-*/
+ *
+ * APLOG_USE_MODULE(rivet);
+ *
+ *  PLEASE: do not use any of APLOG_USE_MODULE, AP_DECLARE_MODULE,
+ *  AP_MODULE_DECLARE_DATA in this header file!
+ *
+ */
 
 /* init.tcl file relative to the server root directory */
 
@@ -116,36 +114,29 @@ typedef struct _rivet_server_conf {
     char*       rivet_before_script;        /* script run before each page      */
     char*       rivet_after_script;         /*            after                 */
 
-    /* ------------------------------------------------------------------------ */
+    /* --------------------------------------------------------------------------- */
 
     /* This flag is used with the above directives. If any of them have changed, it gets set. */
 
-    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     */
+    unsigned int user_scripts_status;
+
+    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
@@ -204,20 +195,32 @@ typedef struct _mpm_bridge_table {
 typedef struct mpm_bridge_status mpm_bridge_status;
 
 typedef struct _mod_rivet_globals {
-    apr_pool_t*             pool;               
-    char*                   rivet_mpm_bridge;       /* name of the MPM bridge                   */
-    server_rec*             server;                 /* default host server_rec obj              */
-    int                     ap_child_shutdown;      /* shutdown inited by the child pool cleanup */
-    int                     vhosts_count;           /* Number of configured virtual host including 
-                                                     * the root server thus it's supposed to be >= 1 */
-	char*				    default_handler;		/* Default request handler code             */
-	int					    default_handler_size;	/* Size of the default_handler buffer       */
-    rivet_thread_interp**   server_interps;         /* 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 */
-    mpm_bridge_status*      mpm;                    /* bridge private control structure         */
+    apr_pool_t*         pool;               
+    char*               rivet_mpm_bridge;       /* name of the MPM bridge                   */
+    server_rec*         server;                 /* default host server_rec obj              */
+    int                 ap_child_shutdown;      /* shutdown inited by the child pool cleanup */
+    int                 vhosts_count;           /* Number of configured virtual host including   *
+                                                 * the root server thus it's supposed to be >= 1 */
+    char*               default_handler;		/* Default request handler code             */
+    int                 default_handler_size;	/* Size of the default_handler buffer       */
+    rivet_thread_interp** server_interps;       /* 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;
+    apr_thread_mutex_t* req_mutex;
 #endif
 } mod_rivet_globals;
 
@@ -248,12 +251,25 @@ typedef struct _thread_worker_private {
 
 /* eventually we will transfer 'global' variables in here and 'de-globalize' them */
 
-//typedef struct _rivet_interp_globals {
-//    Tcl_Namespace*      rivet_ns;           /* Rivet commands namespace             */
-//} rivet_interp_globals; 
+typedef struct _rivet_interp_globals {
+    Tcl_Namespace*      rivet_ns;           /* Rivet commands namespace             */
+} rivet_interp_globals;
 
 rivet_server_conf *Rivet_GetConf(request_rec *r);
 
+/*
+ * Petasis, 04/08/2017: I think the following is wrong, as both "functions" are
+ * defined through preprocessor definitions in http_config.h. At least under
+ * windows, they do not exist as functions in libhttpd.lib.
+ *
+#ifdef ap_get_module_config
+#undef ap_get_module_config
+#endif
+#ifdef ap_set_module_config
+#undef ap_set_module_config
+#endif
+*/
+
 #define RIVET_SERVER_CONF(module) (rivet_server_conf *)ap_get_module_config(module, &rivet_module)
 #define RIVET_NEW_CONF(p)         (rivet_server_conf *)apr_pcalloc(p, sizeof(rivet_server_conf))
 
@@ -281,6 +297,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_cache.c b/src/mod_rivet_ng/mod_rivet_cache.c
index 192378f..151c8ce 100644
--- a/src/mod_rivet_ng/mod_rivet_cache.c
+++ b/src/mod_rivet_ng/mod_rivet_cache.c
@@ -18,9 +18,8 @@
     under the License.
 */
 
-/* $Id: */
-
 #include <apr_strings.h>
+#include <mpm_common.h>
 
 #include "mod_rivet.h"
 
@@ -34,6 +33,23 @@
 
 extern mod_rivet_globals* module_globals;
 
+
+/*
+ * -- RivetCache_DefaultSize
+ *
+ * Basic determination of a default size for the Rivet cache
+ *
+ */
+
+int RivetCache_DefaultSize (void)
+{
+    if (ap_max_requests_per_child != 0) {
+        return  (ap_max_requests_per_child / 5);
+    } else {
+        return 50;
+    }
+}
+
 /*
  * -- RivetCache_Create 
  *
@@ -127,11 +143,23 @@ void RivetCache_Cleanup (rivet_thread_private* private,rivet_thread_interp* rive
 
         ct++;
     }
-    apr_pool_clear(rivet_interp->pool);
+    apr_pool_destroy(rivet_interp->pool);
     
-    rivet_interp->objCacheList = apr_pcalloc (rivet_interp->pool,(signed)(rivet_interp->cache_size*sizeof(char *)));
-    rivet_interp->cache_free = rivet_interp->cache_size;
+    /* let's recreate the cache list */
 
+    if (apr_pool_create(&rivet_interp->pool, private->pool) != APR_SUCCESS)
+    {
+        ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, module_globals->server, 
+                     MODNAME ": could not recreate cache private pool. Cache disabled");
+        rivet_interp->cache_free = rivet_interp->cache_size = 0;
+    }
+    else
+    {
+        rivet_interp->objCacheList = apr_pcalloc (rivet_interp->pool, 
+                                                (signed)(rivet_interp->cache_size*sizeof(char *)));
+        rivet_interp->cache_free = rivet_interp->cache_size;
+    }
+    
 }
 
 /* 
@@ -160,27 +188,49 @@ char* RivetCache_MakeKey (apr_pool_t*   pool,
 /*
  * -- RivetCache_EntryLookup
  *
- * Cache entry lookiup. A hash table lookup key is created and an entry
+ * Cache entry lookup. A hash table lookup key is created and an entry
  * searched in the cache. If an entry is not found the function returns NULL
  *
  * Arguments:
- *      char*                hashKey    - key to the cache
- *      rivet_thread_interp* interp_obj - interpreter object
+ *      rivet_thread_interp* rivet_interp - interpreter object
+ *      char*                hashKey      - key to the cache entry
  *
  * Results:
- *      Tcl_HashEntry*       entry object
+ *      Tcl_HashEntry*       entry object - NULL if the entry for hashKey is not
+ *                                          existing
  *
  * Side Effects:
  *
  */
 
-Tcl_HashEntry* RivetCache_EntryLookup (rivet_thread_interp* rivet_interp,char* hashKey,int* isNew)
+Tcl_HashEntry* RivetCache_EntryLookup (rivet_thread_interp* rivet_interp,char* hashKey)
 {
-    Tcl_HashEntry*  entry = NULL;
+    return Tcl_FindHashEntry(rivet_interp->objCache, hashKey);
+}
 
-    entry = Tcl_CreateHashEntry(rivet_interp->objCache, hashKey, isNew);
-    return entry;
+/*
+ * -- RivetCache_CreateEntry
+ *
+ * Cache entry lookup. A hash table lookup key is created and an entry
+ * searched in the cache. If an entry is not found the function returns NULL
+ *
+ * Arguments:
+ *      rivet_thread_interp* rivet_interp - interpreter object
+ *      char*                hashKey      - key to the cache entry
+ *      int*                 isNew        - pointer to an integer. If the
+ *                                          entry create didn't exists isNew
+ *                                          is set to 1
+ *
+ * Results:
+ *      Tcl_HashEntry*       entry object
+ *
+ * Side Effects:
+ *
+ */
 
+Tcl_HashEntry* RivetCache_CreateEntry (rivet_thread_interp* rivet_interp,char* hashKey,int* isNew)
+{
+    return Tcl_CreateHashEntry(rivet_interp->objCache, hashKey, isNew);
 }
 
 /*
diff --git a/src/mod_rivet_ng/mod_rivet_cache.h b/src/mod_rivet_ng/mod_rivet_cache.h
index d30283a..8f86f6e 100644
--- a/src/mod_rivet_ng/mod_rivet_cache.h
+++ b/src/mod_rivet_ng/mod_rivet_cache.h
@@ -21,17 +21,19 @@
 #ifndef __mod_rivet_cache_h__
 #define __mod_rivet_cache_h__
 
+EXTERN int   RivetCache_DefaultSize (void);
 EXTERN void  RivetCache_Create  (rivet_thread_interp* interp_obj);
-EXTERN void  RivetCache_Destroy (rivet_thread_private* private,rivet_thread_interp* rivet_interp);
 EXTERN void  RivetCache_Cleanup (rivet_thread_private* private,rivet_thread_interp* rivet_interp);
 EXTERN char* RivetCache_MakeKey (apr_pool_t* pool, char*         filename,
                                                    time_t        ctime, 
                                                    time_t        mtime,
                                                    unsigned int  user_conf,
                                                    int           toplevel);
-EXTERN Tcl_HashEntry* RivetCache_EntryLookup (rivet_thread_interp* rivet_interp,char* hashKey,int* isNew);
+EXTERN Tcl_HashEntry* RivetCache_EntryLookup (rivet_thread_interp* rivet_interp,char* hashKey);
+EXTERN Tcl_HashEntry* RivetCache_CreateEntry (rivet_thread_interp* rivet_interp,char* hashKey,int* isNew);
 EXTERN Tcl_Obj* RivetCache_FetchScript (Tcl_HashEntry* entry);
 EXTERN int RivetCache_StoreScript(rivet_thread_interp* rivet_interp, Tcl_HashEntry* entry, Tcl_Obj* script);
 EXTERN void RivetCache_DeleteEntry (Tcl_HashEntry *entry);
+EXTERN void RivetCache_Destroy (rivet_thread_private* private,rivet_thread_interp* rivet_interp);
 
 #endif /* __mod_rivet_cache_h__ */
diff --git a/src/mod_rivet_ng/mod_rivet_common.c b/src/mod_rivet_ng/mod_rivet_common.c
index 59d3ff4..6bf2de2 100644
--- a/src/mod_rivet_ng/mod_rivet_common.c
+++ b/src/mod_rivet_ng/mod_rivet_common.c
@@ -24,10 +24,9 @@
 #include <httpd.h>
 #include <apr_strings.h>
 #include <apr_env.h>
-#include <ap_mpm.h>
 #include <apr_file_io.h>
 #include <apr_file_info.h>
-#include <mpm_common.h>
+#include <ap_mpm.h>
 
 #include "mod_rivet.h"
 #include "rivetChannel.h"
@@ -36,7 +35,6 @@
 #include "rivet.h"
 #include "apache_config.h"
 
-
 /* as long as we need to emulate ap_chdir_file we need to include unistd.h */
 #ifdef RIVET_HAVE_UNISTD_H
 #include <unistd.h>
@@ -130,8 +128,7 @@ Rivet_ReadFile (apr_pool_t* pool,char* filename,char** buffer,int* nbytes)
     return 0;
 }
 
-/*
- *-----------------------------------------------------------------------------
+/*-----------------------------------------------------------------------------
  * Rivet_CreateTclInterp --
  *
  * Arguments:
@@ -146,7 +143,7 @@ Rivet_ReadFile (apr_pool_t* pool,char* filename,char** buffer,int* nbytes)
  */
 
 static Tcl_Interp* 
-Rivet_CreateTclInterp (server_rec* s)
+Rivet_CreateTclInterp (apr_pool_t* pool)
 {
     Tcl_Interp* interp;
 
@@ -156,14 +153,14 @@ Rivet_CreateTclInterp (server_rec* s)
 
     if (interp == NULL)
     {
-        ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, s,
+        ap_log_perror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, pool,
                      MODNAME ": Error in Tcl_CreateInterp, aborting\n");
         exit(1);
     }
 
     if (Tcl_Init(interp) == TCL_ERROR)
     {
-        ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, s,
+        ap_log_perror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, pool,
                      MODNAME ": Error in Tcl_Init: %s, aborting\n",
                      Tcl_GetStringResult(interp));
         exit(1);
@@ -194,20 +191,14 @@ running_scripts* Rivet_RunningScripts ( apr_pool_t* pool,
     {
 		char* request_handler;
 		int	  handler_size;
-
-		//ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_EGENERAL, module_globals->server, 
-        //             MODNAME ": reading request handler %s",rivet_conf->request_handler);
-
+			
 		ap_assert(Rivet_ReadFile(pool,rivet_conf->request_handler,
 		                        &request_handler,&handler_size) == 0);
 
-        scripts->request_processing = Tcl_NewStringObj(request_handler,handler_size);
+        scripts->request_processing = 
+				 Tcl_NewStringObj(request_handler,handler_size);
 
     } else {
-
-		//ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_EGENERAL, module_globals->server, 
-        //             MODNAME ": reading default request handler %s",module_globals->default_handler);
-
         scripts->request_processing = 
 				 Tcl_NewStringObj(module_globals->default_handler,
                                   module_globals->default_handler_size);
@@ -232,6 +223,27 @@ void Rivet_ReleaseRunningScripts (running_scripts* scripts)
     RIVET_SCRIPT_DISPOSE(scripts,request_processing);
 }
 
+/*
+ * -- Rivet_ReleasePerDirScripts
+ *
+ */
+
+void Rivet_ReleasePerDirScripts(rivet_thread_interp* rivet_interp)
+{
+    apr_hash_t*         ht = rivet_interp->per_dir_scripts;
+    apr_hash_index_t*   hi;
+    Tcl_Obj*            script;
+    apr_pool_t*         p = rivet_interp->pool;
+
+    for (hi = apr_hash_first(p,ht); hi; hi = apr_hash_next(hi))
+    {
+        apr_hash_this(hi, NULL, NULL, (void*)(&script));
+        Tcl_DecrRefCount(script);
+    }
+
+    apr_hash_clear(ht);
+}
+
 
 /*
  *---------------------------------------------------------------------
@@ -355,53 +367,39 @@ void Rivet_PerInterpInit(rivet_thread_interp* interp_obj,
   *
   */
 
-rivet_thread_interp* Rivet_NewVHostInterp(rivet_thread_private* private,server_rec* server)
+rivet_thread_interp* Rivet_NewVHostInterp (rivet_thread_private* private,int default_cache_size)
 {
     rivet_thread_interp*    interp_obj = apr_pcalloc(private->pool,sizeof(rivet_thread_interp));
-    rivet_server_conf*      rsc;
-
-    /* The cache size is global so we take it from here */
-    
-    rsc = RIVET_SERVER_CONF (server->module_config);
+    apr_status_t            apr_sts;
 
     /* This calls needs the root server_rec just for logging purposes */
 
-    interp_obj->interp = Rivet_CreateTclInterp(server); 
-    
-    /* We establish the cache size */
-
-    if (rsc->default_cache_size < 0) {
-        if (ap_max_requests_per_child != 0) {
-            interp_obj->cache_size = ap_max_requests_per_child / 5;
-        } else {
-            interp_obj->cache_size = 50;    // Arbitrary number
-        }
-    } else if (rsc->default_cache_size > 0) {
-        interp_obj->cache_size = rsc->default_cache_size;
-    }
-
-    if (interp_obj->cache_size > 0) {
-        interp_obj->cache_free = interp_obj->cache_size;
-    }
+    interp_obj->interp = Rivet_CreateTclInterp(private->pool); 
 
-    /* we now create memory for the cache as subpool of the thread private pool */
- 
-    if (apr_pool_create(&interp_obj->pool, private->pool) != APR_SUCCESS)
+    /* we now create memory from the cache pool as subpool of the thread private pool */
+    
+    apr_sts = apr_pool_create(&interp_obj->pool, private->pool);
+    if (apr_sts != APR_SUCCESS)
     {
-        ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, server, 
+        ap_log_perror(APLOG_MARK, APLOG_ERR, apr_sts, private->pool, 
                      MODNAME ": could not initialize cache private pool");
         return NULL;
     }
 
-    ap_assert(interp_obj->pool != private->pool);
+    if (default_cache_size < 0) {
+        interp_obj->cache_size = RivetCache_DefaultSize();
+    } else if (default_cache_size > 0) {
+        interp_obj->cache_size = default_cache_size;
+    }
+
+    interp_obj->cache_free = interp_obj->cache_size;
 
-    /* Initialize cache structures */
+    // Initialize cache structures
 
     if (interp_obj->cache_size) {
         RivetCache_Create(interp_obj); 
     }
 
-    interp_obj->channel         = NULL;
     interp_obj->flags           = 0;
     interp_obj->scripts         = (running_scripts *) apr_pcalloc(private->pool,sizeof(running_scripts));
     interp_obj->per_dir_scripts = apr_hash_make(private->pool); 
@@ -415,11 +413,11 @@ rivet_thread_interp* Rivet_NewVHostInterp(rivet_thread_private* private,server_r
  *
  * -- Rivet_CreateRivetChannel
  *
- * Creates a channel 
+ * Creates a channel and registers with to the interpreter
  *
  *  Arguments:
  *
- *     - apr_pool_t* pPool: a pointer to an APR memory pool
+ *     - apr_pool_t*        pPool: a pointer to an APR memory pool
  *
  *  Returned value:
  *
@@ -449,13 +447,11 @@ Rivet_CreateRivetChannel(apr_pool_t* pPool, apr_threadkey_t* rivet_thread_key)
      * programmer does a "flush stdout" or the page is completed.
      */
 
-    Tcl_SetChannelBufferSize (*outchannel,TCL_MAX_CHANNEL_BUFFER_SIZE);
+    Tcl_SetChannelBufferSize (*outchannel, TCL_MAX_CHANNEL_BUFFER_SIZE);
 
     return outchannel;
 }
 
-
-
 /*-----------------------------------------------------------------------------
  *
  * -- Rivet_ReleaseRivetChannel
diff --git a/src/mod_rivet_ng/mod_rivet_common.h b/src/mod_rivet_ng/mod_rivet_common.h
index 27a6d68..dc698bb 100644
--- a/src/mod_rivet_ng/mod_rivet_common.h
+++ b/src/mod_rivet_ng/mod_rivet_common.h
@@ -28,14 +28,14 @@ EXTERN void                 Rivet_PerInterpInit (rivet_thread_interp* interp_obj
                                                 server_rec *s, apr_pool_t *p);
 EXTERN void                 Rivet_ReleaseRunningScripts (running_scripts* scripts);
 EXTERN void                 Rivet_CreateCache (apr_pool_t *p, rivet_thread_interp* interp_obj);
-EXTERN rivet_thread_interp* Rivet_NewVHostInterp (rivet_thread_private* private,server_rec* s);
+EXTERN rivet_thread_interp* Rivet_NewVHostInterp (rivet_thread_private* private,int default_cache_size);
 EXTERN int                  Rivet_chdir_file (const char *file);
 EXTERN void                 Rivet_CleanupRequest (request_rec *r);
 EXTERN void                 Rivet_InitServerVariables (Tcl_Interp *interp, apr_pool_t *pool);
 EXTERN void                 Rivet_Panic TCL_VARARGS_DEF (CONST char *, arg1);
 EXTERN Tcl_Channel*         Rivet_CreateRivetChannel (apr_pool_t* pPool, apr_threadkey_t* rivet_thread_key);
 EXTERN rivet_thread_private* Rivet_CreatePrivateData (apr_pool_t* pool, bool create_request_obj);
-//EXTERN rivet_thread_private* Rivet_ExecutionThreadInit (void);
+EXTERN rivet_thread_private* Rivet_ExecutionThreadInit (void);
 EXTERN rivet_thread_private* Rivet_SetupTclPanicProc (void);
 EXTERN void                 Rivet_ReleaseRivetChannel (Tcl_Interp* interp, Tcl_Channel* channel);
 EXTERN int                  Rivet_ReadFile (apr_pool_t* pool,char* filename,char** buffer,int* nbytes);
diff --git a/src/mod_rivet_ng/rivetCore.c b/src/mod_rivet_ng/rivetCore.c
index 5dc9a1b..3c115b1 100644
--- a/src/mod_rivet_ng/rivetCore.c
+++ b/src/mod_rivet_ng/rivetCore.c
@@ -202,7 +202,7 @@ TCL_CMD_HEADER( Rivet_MakeURL )
 TCL_CMD_HEADER( Rivet_Parse )
 {
     rivet_thread_private*   private;
-    char*                   filename;
+    char*                   filename = 0;
     apr_status_t            stat_s;
     apr_finfo_t             finfo_b;
     char*                   cache_key;
@@ -210,7 +210,6 @@ TCL_CMD_HEADER( Rivet_Parse )
     Tcl_HashEntry*          entry  = NULL;
     Tcl_Obj*                script = NULL;
     int                     result;
-    int                     isNew;
 
     THREAD_PRIVATE_DATA(private)
     CHECK_REQUEST_REC(private,"::rivet::parse")
@@ -242,12 +241,12 @@ TCL_CMD_HEADER( Rivet_Parse )
             /* we parse and compose the script ourselves before passing it to Tcl_EvalObjEx */
 
             Tcl_IncrRefCount(outbuf);
-            Tcl_AppendToObj(outbuf,"puts -nonewline \"", -1);
+            Tcl_AppendToObj(outbuf, "puts -nonewline \"", -1);
 
             /* If we are not inside a <? ?> section, add the closing ". */
             if (Rivet_Parser(outbuf, script) == 0)
             {
-                Tcl_AppendToObj(outbuf,"\"\n", 2);
+                Tcl_AppendToObj(outbuf, "\"\n", 2);
             } 
 
             Tcl_AppendToObj(outbuf,"\n",-1);
@@ -285,14 +284,14 @@ TCL_CMD_HEADER( Rivet_Parse )
     /* */
 
     cache_key = 
-        RivetCache_MakeKey (private->pool,filename,
+        RivetCache_MakeKey( private->pool,filename,
                             finfo_b.ctime,finfo_b.mtime,
                             IS_USER_CONF(private->running_conf),0);
 
     rivet_interp = RIVET_PEEK_INTERP(private,private->running_conf);
-    entry = RivetCache_EntryLookup (rivet_interp,cache_key,&isNew);
+    entry = RivetCache_EntryLookup (rivet_interp,cache_key);
 
-    if (isNew)
+    if (entry == NULL)
     {
         script = Tcl_NewObj();
         Tcl_IncrRefCount(script);
@@ -301,16 +300,37 @@ TCL_CMD_HEADER( Rivet_Parse )
         if (result != TCL_OK)
         {
             Tcl_AddErrorInfo(interp,apr_pstrcat(private->pool,"Could not read file ",filename,NULL));
+            Tcl_DecrRefCount(script);
             return result;
         }
-        
-        RivetCache_StoreScript(rivet_interp,entry,script);
+
+        if (rivet_interp->cache_free > 0)
+        {
+            int isNew;
+            Tcl_HashEntry* entry;
+
+            entry = RivetCache_CreateEntry (rivet_interp,cache_key,&isNew);
+            ap_assert(isNew == 1);
+            RivetCache_StoreScript(rivet_interp,entry,script);
+        }
+        else if ((rivet_interp->flags & RIVET_CACHE_FULL) == 0)
+        {
+            rivet_interp->flags |= RIVET_CACHE_FULL;
+            ap_log_error (APLOG_MARK, APLOG_NOTICE, APR_EGENERAL, private->r->server,"%s %s (%s),",
+                                                                  "Rivet cache full when parsing ",
+                                                                  private->r->filename,
+                                                                  private->r->server->server_hostname);
+        }
+
+        result = Tcl_EvalObjEx(interp,script,0);
         Tcl_DecrRefCount(script);
+        return result;
+               
     } else {
         script = RivetCache_FetchScript(entry);
+        return Tcl_EvalObjEx(interp,script,0); 
     }
 
-    return Tcl_EvalObjEx(interp,script,0); 
 }
 
 /*
@@ -1017,6 +1037,7 @@ TCL_CMD_HEADER( Rivet_ApacheTable )
     return TCL_OK;
 }
 
+
 /*
  *-----------------------------------------------------------------------------
  *
@@ -1425,7 +1446,7 @@ TCL_CMD_HEADER( Rivet_EnvCmd )
  *
  *      - non threaded MPMs: the child process exits for good
  *      - threaded MPMs: the child process exits after all Tcl threads
- *        are told to exit
+ *      are told to exit
  *
  *-----------------------------------------------------------------------------
  */
@@ -1433,7 +1454,7 @@ TCL_CMD_HEADER( Rivet_EnvCmd )
 TCL_CMD_HEADER( Rivet_ExitCmd )
 {
     int value;
-    rivet_thread_private* private;
+    rivet_thread_private*   private;
     char* errorMessage = "page generation interrupted by exit command";
 
     if ((objc != 1) && (objc != 2)) {
@@ -1859,7 +1880,6 @@ TCL_CMD_HEADER( Rivet_UrlScript )
     unsigned int         user_conf; 
     time_t               ctime;
     time_t               mtime;
-    int                  isNew;
 
     THREAD_PRIVATE_DATA(private)
     CHECK_REQUEST_REC(private,"::rivet::url_script")
@@ -1871,8 +1891,8 @@ TCL_CMD_HEADER( Rivet_UrlScript )
     mtime = private->r->finfo.mtime;
     cache_key = RivetCache_MakeKey(private->pool,private->r->filename,ctime,mtime,user_conf,1);
 
-    entry = RivetCache_EntryLookup (rivet_interp,cache_key,&isNew);
-    if (isNew)
+    entry = RivetCache_EntryLookup (rivet_interp,cache_key);
+    if (entry == NULL)
     {
         Tcl_Interp*     interp;
         
@@ -1880,7 +1900,6 @@ TCL_CMD_HEADER( Rivet_UrlScript )
 
         script = Tcl_NewObj();
         Tcl_IncrRefCount(script);
-
         /*
          * We check whether we are dealing with a pure Tcl script or a Rivet template.
          * Actually this check is done only if we are processing a toplevel file, every nested
@@ -1898,23 +1917,41 @@ TCL_CMD_HEADER( Rivet_UrlScript )
 
         }
 
-        if (result != TCL_OK)
+        if (result == TCL_OK)
         {
-            // Hash cleanup
-            RivetCache_DeleteEntry(entry);
+            /* let's check the cache for free entries */
 
-            Tcl_DecrRefCount(script);
-            return result;
+            if (rivet_interp->cache_free > 0)
+            {
+                int isNew;
+                Tcl_HashEntry* entry;
+
+                entry = RivetCache_CreateEntry (rivet_interp,cache_key,&isNew);
+    
+                /* Sanity check: we are here for this reason */
+
+                ap_assert(isNew == 1);
+            
+                /* we proceed storing the script in the cache */
+
+                RivetCache_StoreScript(rivet_interp,entry,script);
+            }
+            else if ((rivet_interp->flags & RIVET_CACHE_FULL) == 0)
+            {
+                rivet_interp->flags |= RIVET_CACHE_FULL;
+                ap_log_error (APLOG_MARK, APLOG_NOTICE, APR_EGENERAL,private->r->server,"%s %s (%s),",
+                                                                      "Rivet cache full when serving ",
+                                                                      private->r->filename,
+                                                                      private->r->server->server_hostname);
+            }
         }
+        Tcl_SetObjResult(rivet_interp->interp, script);
+        Tcl_DecrRefCount(script);
 
-        RivetCache_StoreScript(rivet_interp,entry,script);
-    }
-    else
-    {
-        script = RivetCache_FetchScript(entry);
+    } else {
+        Tcl_SetObjResult(rivet_interp->interp,RivetCache_FetchScript(entry));
     }
 
-    Tcl_SetObjResult(rivet_interp->interp, script);
     return TCL_OK;
 }
 
@@ -1997,6 +2034,64 @@ TCL_CMD_HEADER( Rivet_GetThreadId )
     Tcl_SetObjResult(interp,Tcl_NewStringObj(buff,strlen(buff)));
     return TCL_OK;
 }
+
+#ifdef RIVET_DEBUG_BUILD
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * Rivet_CacheContent --
+ *
+ *      Dumping in a list the cache content. For debugging purposes.
+ *      This command will be placed within conditional compilation and
+ *      documented within the 'Rivet Internals' section of the manual
+ *
+ * Results:
+ *      
+ *      a Tcl list of the keys in the interpreter cache
+ *
+ * Side Effects:
+ *
+ *      none
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+TCL_CMD_HEADER( Rivet_CacheContent )
+{
+    Tcl_Obj*                entry_list;
+    rivet_thread_private*   private;
+    rivet_thread_interp*    rivet_interp;
+    int                     ep;
+    THREAD_PRIVATE_DATA(private)
+    CHECK_REQUEST_REC(private,"::rivet::cache_content")
+
+    rivet_interp = RIVET_PEEK_INTERP(private,private->running_conf);
+    interp = rivet_interp->interp;
+    
+    entry_list = Tcl_NewObj();
+    Tcl_IncrRefCount(entry_list);
+
+    ep = rivet_interp->cache_size - 1;
+    
+    while ((ep >= 0) && (rivet_interp->objCacheList[ep]))
+    {
+        int tcl_status;
+
+        tcl_status = Tcl_ListObjAppendElement(interp,entry_list,Tcl_NewStringObj(rivet_interp->objCacheList[ep],-1));
+
+        if (tcl_status != TCL_OK) {
+            return tcl_status;
+        }
+
+        ep--;
+    }
+    Tcl_SetObjResult(interp,entry_list);
+    Tcl_DecrRefCount(entry_list);
+    return TCL_OK;
+}
+
+#endif /* RIVET_DEBUG_BUILD */
+
 /*
  *-----------------------------------------------------------------------------
  *
@@ -2041,7 +2136,11 @@ Rivet_InitCore(rivet_thread_interp* interp_obj,rivet_thread_private* private)
     RIVET_OBJ_CMD ("exit",Rivet_ExitCmd,private);
     RIVET_OBJ_CMD ("url_script",Rivet_UrlScript,private);
     RIVET_OBJ_CMD ("thread_id",Rivet_GetThreadId,private);
-
+    
+#ifdef RIVET_DEBUG_BUILD
+    /* code compiled conditionally for debugging */
+    RIVET_OBJ_CMD ("cache_content",Rivet_CacheContent,private);
+#endif
 #ifdef TESTPANIC
     RIVET_OBJ_CMD ("testpanic",TestpanicCmd,private);
 #endif
diff --git a/src/mod_rivet_ng/rivetInspect.c b/src/mod_rivet_ng/rivetInspect.c
index 7a4c231..92d454c 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>
@@ -86,10 +84,11 @@ enum confIndices {
                     request_handler,
                     export_rivet_ns,
                     import_rivet_ns,
-                    single_thread_exit,
                     conf_index_terminator 
 };
 
+extern mod_rivet_globals* module_globals;
+
 /* 
  * -- Rivet_ReadConfParameter
  *
@@ -141,15 +140,14 @@ 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;
-        case single_thread_exit:        int_value = Tcl_NewIntObj(rsc->single_thread_exit); break;
         default: return NULL;
     }
 
diff --git a/src/mod_rivet_ng/rivet_lazy_mpm.c b/src/mod_rivet_ng/rivet_lazy_mpm.c
index e889880..5145c45 100644
--- a/src/mod_rivet_ng/rivet_lazy_mpm.c
+++ b/src/mod_rivet_ng/rivet_lazy_mpm.c
@@ -34,9 +34,9 @@
 #include "rivetChannel.h"
 #include "apache_config.h"
 
-DLLIMPORT mod_rivet_globals* module_globals;
-DLLIMPORT apr_threadkey_t*   rivet_thread_key;
-module rivet_module;
+extern DLLIMPORT mod_rivet_globals*   module_globals;
+extern DLLIMPORT apr_threadkey_t*     rivet_thread_key;
+extern DLLIMPORT module rivet_module;
 
 enum
 {
@@ -58,7 +58,7 @@ typedef struct lazy_tcl_worker {
     request_rec*        r;
     int                 ctype;
     int                 ap_sts;
-    rivet_server_conf*  conf;               /* rivet_server_conf* record            */
+    rivet_server_conf*  conf;               /* rivet_server_conf* record                */
 } lazy_tcl_worker;
 
 /* virtual host thread queue descriptor */
@@ -73,8 +73,6 @@ typedef struct vhost_iface {
 
 typedef struct mpm_bridge_status {
     apr_thread_mutex_t* mutex;
-    //int                 exit_command;
-    //int                 exit_command_status;
     int                 server_shutdown;    /* the child process is shutting down       */
     vhost*              vhosts;             /* array of vhost descriptors               */
 } mpm_bridge_status;
@@ -157,12 +155,7 @@ static void* APR_THREAD_FUNC request_processor (apr_thread_t *thd, void *data)
 
     /* Rivet_ExecutionThreadInit creates and returns the thread private data. */
 
-    private = Rivet_CreatePrivateData(apr_thread_pool_get(thd),true);
-    ap_assert(private != NULL);
-
-    //private->channel = Rivet_CreateRivetChannel(private->pool,rivet_thread_key);
-
-    Rivet_SetupTclPanicProc();
+    private = Rivet_ExecutionThreadInit();
 
     /* A bridge creates and stores in private->ext its own thread private
      * data. The lazy bridge is no exception. We just need a flag controlling 
@@ -171,7 +164,7 @@ static void* APR_THREAD_FUNC request_processor (apr_thread_t *thd, void *data)
     private->ext = apr_pcalloc(private->pool,sizeof(mpm_bridge_specific));
     private->ext->keep_going = 1;
 
-    private->ext->interp = Rivet_NewVHostInterp(private,w->server);
+    private->ext->interp = Rivet_NewVHostInterp(private,rsc->default_cache_size);
     //RIVET_POKE_INTERP(private,rsc,Rivet_NewVHostInterp(private,w->server));
     private->ext->interp->channel = Rivet_CreateRivetChannel(private->pool,rivet_thread_key);
 
@@ -260,7 +253,7 @@ static void* APR_THREAD_FUNC request_processor (apr_thread_t *thd, void *data)
 
     /* If single thread exit is enabled we delete the Tcl interp */
 
-    if (!rsc->single_thread_exit) 
+    if (!module_globals->single_thread_exit) 
     {
         Tcl_DeleteInterp(private->ext->interp->interp);
     }
@@ -283,7 +276,7 @@ static void* APR_THREAD_FUNC request_processor (apr_thread_t *thd, void *data)
 
 static lazy_tcl_worker* create_worker (apr_pool_t* pool,server_rec* server)
 {
-    lazy_tcl_worker*    w;
+    lazy_tcl_worker* w;
 
     w = apr_pcalloc(pool,sizeof(lazy_tcl_worker));
 
@@ -409,7 +402,9 @@ int LazyBridge_Request (request_rec* r,rivet_req_ctype ctype)
     }
 
     apr_thread_mutex_unlock(mutex);
-    
+
+    /* Locking the thread descriptor structure mutex */    
+
     apr_thread_mutex_lock(w->mutex);
     w->r        = r;
     w->ctype    = ctype;
@@ -437,20 +432,28 @@ int LazyBridge_Request (request_rec* r,rivet_req_ctype ctype)
  */
 
 rivet_thread_interp* LazyBridge_Interp (rivet_thread_private* private,
-                                        rivet_server_conf*    conf,
-                                        rivet_thread_interp*  interp)
+                                      rivet_server_conf*    conf,
+                                      rivet_thread_interp*  interp)
 {
     if (interp != NULL) { private->ext->interp = interp; }
 
     return private->ext->interp;
 }
 
+/*
+ * -- LazyBridge_Finalize
+ *
+ * Bridge thread and resources shutdown
+ *
+ */
+
 apr_status_t LazyBridge_Finalize (void* data)
 {
     int idx;
     server_rec* server = (server_rec*) data;
-    rivet_server_conf* conf = RIVET_SERVER_CONF(((server_rec*) data)->module_config);
+    rivet_server_conf* conf = RIVET_SERVER_CONF(server->module_config);
    
+    module_globals->mpm->server_shutdown = 1;
     for (idx = 0; idx < module_globals->vhosts_count; idx++)
     {
         int try;
@@ -516,50 +519,46 @@ int LazyBridge_ExitHandler(rivet_thread_private* private)
 
     private->ext->keep_going = 0;
 
-    /*
-     * This is the only place where exit_command and 
-     * exit_command_status are set, anywere alse these
-     * fields are only read. We lock on writing to synchronize
-     * with other threads that might try to access
-     * this info. That means that in the unlikely case
-     * of several threads calling ::rivet::exit 
-     * simultaneously the first sets the exit code.
-     * This is just terrible, it highlights the bad habit
-     * of calling 'exit' when programming with mod_rivet
-     * and calls out for a version of Tcl with which
-     * we could safely call Tcl_DeleteInterp and then terminate
-     * a single thread
-    
-    apr_thread_mutex_lock(module_globals->mpm->mutex);
-    if (module_globals->mpm->exit_command == 0)
+    if (!module_globals->single_thread_exit)
     {
-        module_globals->mpm->exit_command = 1;
-        module_globals->mpm->exit_command_status = private->exit_status;
-    }
-    apr_thread_mutex_unlock(module_globals->mpm->mutex);
-     */
-
-    if (!private->running_conf->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() */
      
-        module_globals->mpm->server_shutdown = 1;
         LazyBridge_Finalize(private->r->server);
 
-    }
+    } 
 
     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,
     LazyBridge_ExitHandler,
-    LazyBridge_Interp,
-    false
+    LazyBridge_Interp
 };
diff --git a/src/mod_rivet_ng/rivet_prefork_mpm.c b/src/mod_rivet_ng/rivet_prefork_mpm.c
index 983f23d..c023b2e 100644
--- a/src/mod_rivet_ng/rivet_prefork_mpm.c
+++ b/src/mod_rivet_ng/rivet_prefork_mpm.c
@@ -17,14 +17,16 @@
     KIND, either express or implied.  See the License for the
     specific language governing permissions and limitations
     under the License.
-*/
+ */
 
 #include <apr_strings.h>
 
 #include "mod_rivet.h"
 #include "mod_rivet_common.h"
 #include "mod_rivet_generator.h"
+#include "mod_rivet_cache.h"
 #include "httpd.h"
+#include "rivetChannel.h"
 #include "apache_config.h"
 #include "rivet.h"
 #include "rivetCore.h"
@@ -36,6 +38,13 @@ module           rivet_module;
 
 extern TclWebRequest* TclWeb_NewRequestObject (apr_pool_t *p);
 
+/*
+ *  -- PreforkBridge_ServerInit
+ *
+ * Bridge server wide inizialization:
+ *
+ */
+
 int PreforkBridge_ServerInit (apr_pool_t *pPool, 
                                apr_pool_t *pLog,
                                apr_pool_t *pTemp, server_rec *server)
@@ -55,10 +64,26 @@ int PreforkBridge_ServerInit (apr_pool_t *pPool,
 
     if (server_interps[server_idx] == NULL)
     {
-        server_interps[server_idx] = Rivet_NewVHostInterp(private,server);
+        server_interps[server_idx] = Rivet_NewVHostInterp(private,rsc->default_cache_size);
         Rivet_PerInterpInit(server_interps[server_idx],private,server,pPool);
     }
 
+    /* Whether single_thread_exit is 1 or 0 doesn't make any difference for
+     * the prefork bridge, we set the default value anyway in case it hadn't been
+     * set already in the configuration */
+
+    if (module_globals->single_thread_exit == SINGLE_THREAD_EXIT_UNDEF)
+    {
+        module_globals->single_thread_exit = 0;
+    }
+
+    /* The root interpreter is created without a rivet cache (that wouldn't make sense
+     * in that context. We create the cache now */
+
+    if (module_globals->server_interps[server_idx]->cache_size) {
+        RivetCache_Create(module_globals->server_interps[server_idx]); 
+    }
+
    /*
     * Looping through all the server records and creating (or assigning
     * when no virtual host interpreters are required) interpreters
@@ -80,13 +105,13 @@ int PreforkBridge_ServerInit (apr_pool_t *pPool,
 
         if (server_interps[idx] == NULL)
         {
-            if (rsc->separate_virtual_interps == 0)
+            if (module_globals->separate_virtual_interps == 0)
             {
                 server_interps[idx] = server_interps[server_idx];
             }
             else
             {
-                server_interps[idx] = Rivet_NewVHostInterp(private,s);
+                server_interps[idx] = Rivet_NewVHostInterp(private,rsc->default_cache_size);
                 Rivet_PerInterpInit(server_interps[idx],private,s,pPool);
             }
         }
@@ -279,19 +304,24 @@ int PreforkBridge_ExitHandler(rivet_thread_private* private)
 {
     Tcl_Exit(private->exit_status);
 
-    /* it will never get here */
+    /* actually we'll never get here but we return
+     * the Tcl return code anyway to silence the 
+     * compilation warning
+     */
     return TCL_OK;
 }
 
 rivet_thread_interp* PreforkBridge_Interp (rivet_thread_private* private,
-                                            rivet_server_conf*    conf,
-                                            rivet_thread_interp*  interp)
+                                         rivet_server_conf*    conf,
+                                         rivet_thread_interp*  interp)
 {
     if (interp != NULL) { private->ext->interps[conf->idx] = interp; }
 
     return private->ext->interps[conf->idx];   
 }
 
+/* Table of bridge control functions */
+
 DLLEXPORT
 RIVET_MPM_BRIDGE {
     PreforkBridge_ServerInit,
diff --git a/src/mod_rivet_ng/rivet_worker_mpm.c b/src/mod_rivet_ng/rivet_worker_mpm.c
index 5b710cf..5eed91d 100644
--- a/src/mod_rivet_ng/rivet_worker_mpm.c
+++ b/src/mod_rivet_ng/rivet_worker_mpm.c
@@ -240,10 +240,10 @@ static void Worker_CreateInterps (rivet_thread_private* private,rivet_thread_int
         
         server_conf = RIVET_SERVER_CONF(s->module_config);
 
-        if ((s == server) || (server_conf->separate_virtual_interps))
+        if ((s == server) || (module_globals->separate_virtual_interps))
         {
 
-            interp_obj = Rivet_NewVHostInterp(private,s);
+            interp_obj = Rivet_NewVHostInterp(private,server_conf->default_cache_size);
             Rivet_PerInterpInit(interp_obj,private,s,private->pool);
             if (s == server) { root_interp = interp_obj; }
 
@@ -381,9 +381,9 @@ static void* APR_THREAD_FUNC request_processor (apr_thread_t *thd, void *data)
     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, module_globals->server, "processor thread orderly exit");
 
     {
-        rivet_server_conf* rsc = RIVET_SERVER_CONF(module_globals->server->module_config);
+        //rivet_server_conf* rsc = RIVET_SERVER_CONF(module_globals->server->module_config);
 
-        if (rsc->single_thread_exit)
+        if (module_globals->single_thread_exit)
         {
             //Rivet_ProcessorCleanup(private);
         }
@@ -826,7 +826,7 @@ int Worker_Bridge_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;
 
diff --git a/src/mod_rivet_ng/worker_prefork_common.c b/src/mod_rivet_ng/worker_prefork_common.c
index 7972430..2dea7c4 100644
--- a/src/mod_rivet_ng/worker_prefork_common.c
+++ b/src/mod_rivet_ng/worker_prefork_common.c
@@ -86,8 +86,8 @@ rivet_thread_private* Rivet_SetupInterps (rivet_thread_private* private)
         interp_obj = private->ext->interps[rsc->idx];
 
         if ((s != root_server) &&
-            root_server_conf->separate_channels && 
-            root_server_conf->separate_virtual_interps)
+            module_globals->separate_channels && 
+            module_globals->separate_virtual_interps)
         {
             channel = Rivet_CreateRivetChannel(private->pool,rivet_thread_key);
         } 
@@ -114,7 +114,7 @@ rivet_thread_private* Rivet_SetupInterps (rivet_thread_private* private)
 
         function = rsc->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 = interp_obj->interp;
@@ -166,7 +166,7 @@ rivet_thread_private* Rivet_SetupInterps (rivet_thread_private* private)
 
 void Rivet_ProcessorCleanup (rivet_thread_private* private)
 {
-    rivet_server_conf*      rsc = RIVET_SERVER_CONF(module_globals->server->module_config);
+    //rivet_server_conf*      rsc = RIVET_SERVER_CONF(module_globals->server->module_config);
     server_rec*             s;
     server_rec*             server;
 
@@ -194,14 +194,14 @@ void Rivet_ProcessorCleanup (rivet_thread_private* private)
     {
         int i = 0;
 
-        if ((i == 0) || rsc->separate_virtual_interps)
+        if ((i == 0) || module_globals->separate_virtual_interps)
         {
             RivetCache_Destroy(private,private->ext->interps[i]);
             Tcl_DeleteInterp(private->ext->interps[i]->interp);
             Rivet_ReleaseRivetChannel(private->ext->interps[i]->interp,private->ext->interps[i]->channel);
         }
 
-        if ((i > 0) && rsc->separate_channels) 
+        if ((i > 0) && module_globals->separate_channels) 
             Rivet_ReleaseRivetChannel(private->ext->interps[i]->interp,private->ext->interps[i]->channel);
 
         Rivet_ReleaseRunningScripts(private->ext->interps[i]->scripts);
@@ -209,3 +209,4 @@ void Rivet_ProcessorCleanup (rivet_thread_private* private)
         i++;
     } 
 }
+
diff --git a/src/rivet.h b/src/rivet.h
index 63fde97..ddbc522 100644
--- a/src/rivet.h
+++ b/src/rivet.h
@@ -116,7 +116,7 @@ EXTERN int Rivet_InitWWW(Tcl_Interp *interp);
     interp_obj = interps[rsc->idx]; \
     for (s = server; s != NULL; s = s->next) { \
         aFunction (s, interp_obj); \
-        if (rsc->separate_virtual_interps == 0) { break; } \
+        if (module_globals->separate_virtual_interps == 0) { break; } \
     } \
 }
 
@@ -130,7 +130,7 @@ EXTERN int Rivet_InitWWW(Tcl_Interp *interp);
     interp_obj = interps[rsc->idx]; \
     for (s = server; s != NULL; s = s->next) { \
         aFunction (s, interp_obj, __VA_ARGS__ ); \
-        if (rsc->separate_virtual_interps == 0) { break; } \
+        if (module_globals->separate_virtual_interps == 0) { break; } \
     } \
 }
 


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


[tcl-rivet] 06/07: merging changes from master

Posted by mx...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mxmanghi pushed a commit to branch quattuor
in repository https://gitbox.apache.org/repos/asf/tcl-rivet.git

commit 3fdb364642d90efb0ac4e927a8b0c34cdb4ae078
Author: Massimo Manghi <mx...@apache.org>
AuthorDate: Thu Oct 1 22:39:20 2020 +0200

    merging changes from master
---
 .appveyor.yml | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/.appveyor.yml b/.appveyor.yml
index 1f7ef21..843c314 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -61,3 +61,42 @@ build_script:
   - cmd: msbuild Rivet.sln /p:Platform=%RIVET_PLATFORM% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
   - cmd: msbuild INSTALL.vcxproj /p:Platform=%RIVET_PLATFORM% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
 
+after_build:
+  - cmd: set ARTIFACT_DIR=%RIVET_HOME%\artifacts\rivet-%RIVET_VERSION%-windows-%platform%
+  - cmd: echo %cd%
+  - cmd: mkdir %ARTIFACT_DIR%\modules
+  # Copy the installed files into a new directory, so we can zip it...
+  - cmd: copy /y /b %APACHE_ROOT%\modules\mod_rivet.so %ARTIFACT_DIR%\modules
+  - cmd: xcopy %APACHE_ROOT%\bin\rivet%RIVET_VERSION% %ARTIFACT_DIR%\rivet%RIVET_VERSION% /s /e /y /i
+  - cmd: cd %RIVET_HOME%\artifacts && dir
+  - cmd: cd %ARTIFACT_DIR% && dir
+  - cmd: cd %RIVET_HOME%\artifacts && 7z a -tzip rivet-%RIVET_VERSION%-windows-%platform%.zip *
+
+artifacts:
+  - path: '\artifacts\*.zip'
+    type: zip
+    name: rivet-%RIVET_VERSION%-windows-%platform%.zip
+
+deploy:
+  provider: GitHub
+  # The following token belongs to the user "petasis":
+  auth_token:
+    secure: "u2sUa4ovDQsL08AQjtmcIIVmHw6pFqIsT8JSBkMA2Ciebku0slhbTCGDZ19sp0Xt"
+  tag: $(APPVEYOR_REPO_TAG_NAME)
+  release: $(APPVEYOR_REPO_TAG_NAME)
+  description: 'Apache Rivet binaries'
+  artifact: rivet-%RIVET_VERSION%-windows-%platform%.zip
+  draft: true
+  prerelease: true
+  on:
+    branch: master                 # release from master branch only
+    appveyor_repo_tag: true        # deploy on tag push only
+
+## How to trigger a release:
+#  Add a new tag:
+#    git tag rivet-release-test-v3.2.0-1
+#    git push origin --tags
+#
+#  If you want to remove the tag:
+#    git push --delete origin tagName ;# tagName: rivet-release-test-v3.2.0-1
+#    git tag -d tagName


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