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 7db381382295ce3736285e9f8ba604ed59a679e7
Author: Massimo Manghi <mxman...@apache.org>
AuthorDate: Thu May 18 17:12:24 2023 +0200

    Handling the server_rec pointer in the module globals for the benefit of 
logging into the specific virtual host log file during child init stage
---
 ChangeLog                                | 12 +++-
 src/mod_rivet_ng/mod_rivet.c             | 12 ++--
 src/mod_rivet_ng/mod_rivet.h             |  1 +
 src/mod_rivet_ng/mod_rivet_common.c      |  8 +--
 src/mod_rivet_ng/rivetCore.c             | 14 ++++-
 src/mod_rivet_ng/worker_prefork_common.c | 95 ++++++++++++++++++++++++++------
 6 files changed, 111 insertions(+), 31 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 2b82f58..91f4d2f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,13 @@
-2023-05-14 Massimo Manghi <mxman...@apache.org>
+2023-05-18 Massimo Manghi <mxman...@apache.org>
+       * src/mod_rivet_ng/mod_rivet.c:
+       * src/mod_rivet_ng/mod_rivet.h:
+       * src/mod_rivet_ng/mod_rivet_common.c:
+       * src/mod_rivet_ng/rivetCore.c:
+       * src/mod_rivet_ng/worker_prefork_common.c: now storing the server 
record in the intepreter globals
+       to be used by Rivet_LogErrorCmd instead of module_globals->server when 
threads private data are
+       not available (like when ChildInitScript is executed)
+
+2023-05-04 Massimo Manghi <mxman...@apache.org>
        * tests/rivet.test: more contributions provided by Scott Pitcher 
<sco...@svptechnicalservices.com.au>)
        * tests/apachetest/apachetest.tcl: More improvements to the test 
script. Now
        handling also Apache directive IncludeOptional and enabling execution 
control 
@@ -6,7 +15,6 @@
        * tests/post.rvt:
        * tests/post.test: add a test for ::rivet::raw_post
 
-       * 
 2023-04-11 Massimo Manghi <mxman...@apache.org>
        * src/mod_rivet_ng/TclWebapache.c:
        * src/mod_rivet_ng/rivetCore.c:
diff --git a/src/mod_rivet_ng/mod_rivet.c b/src/mod_rivet_ng/mod_rivet.c
index 37549ff..c63efda 100644
--- a/src/mod_rivet_ng/mod_rivet.c
+++ b/src/mod_rivet_ng/mod_rivet.c
@@ -289,15 +289,19 @@ Rivet_RunServerInit (apr_pool_t *pPool, apr_pool_t *pLog, 
apr_pool_t *pTemp, ser
     {
         char* parent_pid_var = NULL;
 
+        /* if the environment variable AP_PARENT_PID is set
+         * we know we are in a child process of the winnt MPM
+         */
+        
         apr_env_get(&parent_pid_var,"AP_PARENT_PID",pTemp);
         if (parent_pid_var != NULL)
         {
-            ap_log_error(APLOG_MARK,APLOG_DEBUG,0,server,
-                        "AP_PARENT_PID found: not running the Tcl server 
script in winnt MPM child process");
+            ap_log_perror(APLOG_MARK,APLOG_INFO,0,pPool,
+                    "AP_PARENT_PID found: not running the Tcl server script in 
winnt MPM child process");
             return OK;
         } else {
-            ap_log_error(APLOG_MARK,APLOG_DEBUG,0,server,
-                        "AP_PARENT_PID undefined, we proceed with server 
initialization");
+            ap_log_perror(APLOG_MARK,APLOG_INFO,0,pPool,
+                     "AP_PARENT_PID undefined, we proceed with server 
initialization");
         }
     }
 
diff --git a/src/mod_rivet_ng/mod_rivet.h b/src/mod_rivet_ng/mod_rivet.h
index c107690..8239c31 100644
--- a/src/mod_rivet_ng/mod_rivet.h
+++ b/src/mod_rivet_ng/mod_rivet.h
@@ -253,6 +253,7 @@ typedef struct _thread_worker_private {
 
 typedef struct _rivet_interp_globals {
     Tcl_Namespace*      rivet_ns;           /* Rivet commands namespace        
     */
+    server_rec*         server;             /* Virtual host server rec         
     */
 } rivet_interp_globals;
 
 rivet_server_conf *Rivet_GetConf(request_rec *r);
diff --git a/src/mod_rivet_ng/mod_rivet_common.c 
b/src/mod_rivet_ng/mod_rivet_common.c
index 35fe13b..2103849 100644
--- a/src/mod_rivet_ng/mod_rivet_common.c
+++ b/src/mod_rivet_ng/mod_rivet_common.c
@@ -250,7 +250,7 @@ void Rivet_ReleasePerDirScripts(rivet_thread_interp* 
rivet_interp)
  *
  * Rivet_PerInterpInit --
  *
- *  Do the initialization that needs to happen to every interpreter.
+ *  Do the interpreter environment creation and initialization.
  *
  * Results:
  *  None.
@@ -283,11 +283,11 @@ void Rivet_PerInterpInit(rivet_thread_interp* interp_obj,
     //Tcl_SetAssocData (interp,"rivet",NULL,globals);
 
     /*
-     * the ::rivet namespace is the only information still stored
-     * in the interpreter global data
+     * we store in the globals some information relevant to
+     * the embedded interpreter work
      */
 
-    /* Rivet commands namespace is created */
+    /* the ::rivet namespace is created */
 
     interp_obj->rivet_ns =
         Tcl_CreateNamespace (interp,RIVET_NS,private,(Tcl_NamespaceDeleteProc 
*)NULL);
diff --git a/src/mod_rivet_ng/rivetCore.c b/src/mod_rivet_ng/rivetCore.c
index c32ed15..82fba23 100644
--- a/src/mod_rivet_ng/rivetCore.c
+++ b/src/mod_rivet_ng/rivetCore.c
@@ -1770,7 +1770,7 @@ TCL_CMD_HEADER( Rivet_InspectCmd )
  *-----------------------------------------------------------------------------
  */
 
-TCL_CMD_HEADER( Rivet_LogErrorCmd )
+TCL_CMD_HEADER(Rivet_LogErrorCmd)
 {
     char *message = NULL;
 
@@ -1855,9 +1855,17 @@ TCL_CMD_HEADER( Rivet_LogErrorCmd )
     /* if we are serving a page, we know our server,
      * else send null for server
      */
-    serverRec = ((private == NULL) || (private->r == NULL)) ? 
module_globals->server : private->r->server;
 
-    ap_log_error (APLOG_MARK, apLogLevel, 0, serverRec, "%s", message);
+    if ((private == NULL) || (private->r == NULL))
+    {
+        rivet_interp_globals* globals = Tcl_GetAssocData(interp, "rivet", 
NULL);
+        serverRec = globals->server;
+    }
+    else
+    {
+        serverRec = private->r->server;
+    }
+    ap_log_error (APLOG_MARK,apLogLevel,0,serverRec,"%s",message);
     return TCL_OK;
 }
 
diff --git a/src/mod_rivet_ng/worker_prefork_common.c 
b/src/mod_rivet_ng/worker_prefork_common.c
index 48c4b36..ec92c33 100644
--- a/src/mod_rivet_ng/worker_prefork_common.c
+++ b/src/mod_rivet_ng/worker_prefork_common.c
@@ -40,6 +40,34 @@ extern DLLIMPORT apr_threadkey_t*   rivet_thread_key;
 extern DLLIMPORT module             rivet_module;
 
 /* -- Rivet_SetupInterps
+ *
+ *
+ */
+
+rivet_thread_interp*
+Rivet_DuplicateVHostInterp(apr_pool_t* pool, rivet_thread_interp* source_obj)
+{
+    rivet_thread_interp* interp_obj = 
apr_pcalloc(pool,sizeof(rivet_thread_interp));
+
+    interp_obj->interp      = source_obj->interp;
+    interp_obj->channel     = source_obj->channel;
+    interp_obj->cache_free  = source_obj->cache_free;
+    interp_obj->cache_size  = source_obj->cache_size;
+
+    /* An intepreter must have its own cache */
+
+    if (interp_obj->cache_size) {
+        RivetCache_Create(source_obj);
+    }
+
+    interp_obj->pool            = source_obj->pool;
+    interp_obj->scripts         = (running_scripts *) 
apr_pcalloc(pool,sizeof(running_scripts));
+    interp_obj->per_dir_scripts = apr_hash_make(pool);
+    interp_obj->flags           = source_obj->flags;
+    return interp_obj;
+}
+
+/* -- Rivet_VirtualHostsInterps
  *
  * The server_rec chain is walked through and server configurations are read to
  * set up the thread private configuration and interpreters database
@@ -60,7 +88,7 @@ extern DLLIMPORT module             rivet_module;
 
 rivet_thread_private* Rivet_SetupInterps (rivet_thread_private* private)
 {
-    server_rec*             s;
+    server_rec*             vhost_server;
     server_rec*             root_server = module_globals->server;
     rivet_server_conf*      root_server_conf;
     void*                   parentfunction;     /* this is topmost 
initialization script */
@@ -77,15 +105,15 @@ rivet_thread_private* Rivet_SetupInterps 
(rivet_thread_private* private)
 
     parentfunction = root_server_conf->rivet_child_init_script;
 
-    for (s = root_server; s != NULL; s = s->next)
+    for (vhost_server = root_server; vhost_server != NULL; vhost_server = 
vhost_server->next)
     {
         rivet_server_conf*      rsc;
         rivet_thread_interp*    interp_obj;
 
-        rsc = RIVET_SERVER_CONF(s->module_config);
+        rsc = RIVET_SERVER_CONF(vhost_server->module_config);
         interp_obj = private->ext->interps[rsc->idx];
 
-        if ((s != root_server) &&
+        if ((vhost_server != root_server) &&
             module_globals->separate_channels &&
             module_globals->separate_virtual_interps)
         {
@@ -97,42 +125,73 @@ rivet_thread_private* Rivet_SetupInterps 
(rivet_thread_private* private)
 
         /* interpreter base running scripts definition and initialization */
 
-        interp_obj->scripts = 
Rivet_RunningScripts(private->pool,interp_obj->scripts,rsc);
-
-        private->ext->interps[rsc->idx] = interp_obj;
+        interp_obj->scripts = Rivet_RunningScripts 
(private->pool,interp_obj->scripts,rsc);
+        RIVET_POKE_INTERP(private,rsc,interp_obj);
 
         /* Basic Rivet packages and libraries are loaded here */
 
-        Rivet_PerInterpInit(interp_obj, private, s, private->pool);
+        if ((interp_obj->flags & RIVET_INTERP_INITIALIZED) == 0)
+        {
+            Rivet_PerInterpInit(interp_obj,private,vhost_server,private->pool);
+        }
 
         /* It seems that allocating from a shared APR memory pool is not 
thread safe,
          * but it's not very well documented actually. In any case we protect 
this
          * memory allocation with a mutex
          */
 
+        /*  this stuff must be allocated from the module global pool which
+         *  has the child process' same lifespan
+         */
+
+        apr_thread_mutex_lock(module_globals->pool_mutex);
+        rsc->server_name = (char*) apr_pstrdup 
(private->pool,vhost_server->server_hostname);
+        apr_thread_mutex_unlock(module_globals->pool_mutex);
+
         /* when configured a child init script gets evaluated */
 
         function = rsc->rivet_child_init_script;
         if (function &&
-            (s == root_server || module_globals->separate_virtual_interps || 
function != parentfunction))
+            (vhost_server == root_server || 
module_globals->separate_virtual_interps || function != parentfunction))
         {
             char*       errmsg = MODNAME ": Error in Child init script: %s";
-            Tcl_Interp* interp = interp_obj->interp;
             Tcl_Obj*    tcl_child_init = Tcl_NewStringObj(function,-1);
+            rivet_interp_globals* globals = NULL;
 
             Tcl_IncrRefCount(tcl_child_init);
-            Tcl_Preserve (interp);
+            Tcl_Preserve (interp_obj->interp);
+
+            /* There is a lot of passing pointers around among various 
structures.
+             * We should understand if this is all that necessary.
+             * Here we assign the server_rec pointer to the interpreter which
+             * is wrong, because without separate interpreters it doens't make
+             * any sense. TODO
+             */
+
+            /* before we run a script we have to store the pointer to the
+             * running configuration in the thread private data. The design has
+             * to improve and running a script must have everything sanely
+             * prepared TODO
+             */
+
+            globals = Tcl_GetAssocData(interp_obj->interp, "rivet", NULL);
+
+            /*
+             * The current server record is stored to enable 
::rivet::apache_log_error and
+             * other commands to log error messages in the virtual host's 
designated log file
+             */
 
+            globals->server = vhost_server;
             private->running_conf = rsc;
 
-            if (Tcl_EvalObjEx(interp,tcl_child_init, 0) != TCL_OK) {
-                ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, root_server, 
errmsg, function);
-                ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, root_server,
-                             "errorCode: %s", Tcl_GetVar(interp, "errorCode", 
0));
-                ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, root_server,
-                             "errorInfo: %s", Tcl_GetVar(interp, "errorInfo", 
0));
+            if (Tcl_EvalObjEx(interp_obj->interp,tcl_child_init, 0) != TCL_OK) 
{
+                ap_log_error(APLOG_MARK, 
APLOG_ERR,APR_EGENERAL,vhost_server,errmsg, function);
+                ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL,vhost_server,
+                             "errorCode: %s", Tcl_GetVar(interp_obj->interp, 
"errorCode", 0));
+                ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL,vhost_server,
+                             "errorInfo: %s", Tcl_GetVar(interp_obj->interp, 
"errorInfo", 0));
             }
-            Tcl_Release (interp);
+            Tcl_Release (interp_obj->interp);
             Tcl_DecrRefCount(tcl_child_init);
         }
     }


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

Reply via email to