You are viewing a plain text version of this content. The canonical link for it is here.
Posted to site-cvs@tcl.apache.org by mx...@apache.org on 2014/07/19 01:23:41 UTC

svn commit: r1611837 - in /tcl/rivet/trunk: ChangeLog src/experimental/mod_rivet.c src/experimental/mod_rivet.h src/experimental/rivetChannel.c

Author: mxmanghi
Date: Fri Jul 18 23:23:40 2014
New Revision: 1611837

URL: http://svn.apache.org/r1611837
Log:

    * src/experimental/mod_rivet.c: working toy module capable of running Tcl scripts with a worker MPM
    * src/experimental/rivetChannel.c: now depending on the thread private data


Modified:
    tcl/rivet/trunk/ChangeLog
    tcl/rivet/trunk/src/experimental/mod_rivet.c
    tcl/rivet/trunk/src/experimental/mod_rivet.h
    tcl/rivet/trunk/src/experimental/rivetChannel.c

Modified: tcl/rivet/trunk/ChangeLog
URL: http://svn.apache.org/viewvc/tcl/rivet/trunk/ChangeLog?rev=1611837&r1=1611836&r2=1611837&view=diff
==============================================================================
--- tcl/rivet/trunk/ChangeLog (original)
+++ tcl/rivet/trunk/ChangeLog Fri Jul 18 23:23:40 2014
@@ -1,3 +1,7 @@
+2014-07-14 Massimo Manghi <mx...@apache.org>
+    * src/experimental/mod_rivet.c: working toy module capable of running Tcl scripts with a worker MPM
+    * src/experimental/rivetChannel.c: now depending on the thread private data
+
 2014-07-17 Massimo Manghi <mx...@apache.org>
     * src/channel/rivetChannel.[c|h]: add preprocessor symbol to prevent multiple includes
 

Modified: tcl/rivet/trunk/src/experimental/mod_rivet.c
URL: http://svn.apache.org/viewvc/tcl/rivet/trunk/src/experimental/mod_rivet.c?rev=1611837&r1=1611836&r2=1611837&view=diff
==============================================================================
--- tcl/rivet/trunk/src/experimental/mod_rivet.c (original)
+++ tcl/rivet/trunk/src/experimental/mod_rivet.c Fri Jul 18 23:23:40 2014
@@ -23,6 +23,7 @@ rivet_server_conf       rsc;
 rivet_interp_globals    interp_globals;
 
 extern Tcl_ChannelType RivetChan;
+apr_threadkey_t*        rivet_thread_key;
 
 int
 Rivet_ParseExecString (TclWebRequest* req, Tcl_Obj* inbuf)
@@ -45,7 +46,7 @@ static void RivetReleaseInterp(int inter
     apr_thread_mutex_unlock(module_globals.mutex);
 }
 
-static int RivetFetchInterp(Tcl_Interp** interp_p, request_rec* req)
+static int RivetFetchInterp(request_rec* req)
 {
     int c;
     int interp_id;
@@ -71,7 +72,6 @@ static int RivetFetchInterp(Tcl_Interp**
                 module_globals.interp_idx = interp_id;
                 module_globals.status[interp_id] = request_processing;
                 module_globals.busy_cnt++;
-                *interp_p = module_globals.interp_a[interp_id];
                 break;
             }
         }
@@ -108,6 +108,7 @@ RivetChildInit (apr_pool_t *pChild, serv
     apr_thread_mutex_create(&module_globals.mutex, APR_THREAD_MUTEX_UNNESTED, pChild);
     apr_thread_mutex_create(&module_globals.channel_mutex, APR_THREAD_MUTEX_UNNESTED, pChild);
     apr_thread_cond_create(&module_globals.cond, pChild);
+    apr_threadkey_private_create (&rivet_thread_key, NULL, pChild);
 
     for (i = 0; i < TCL_INTERPS; i++)
     {
@@ -123,43 +124,33 @@ RivetChildInit (apr_pool_t *pChild, serv
         }
         module_globals.interp_a[i] = interp;
         module_globals.status[i]   = idle;
-    }
-
-    outchannel  = apr_pcalloc (pChild, sizeof(Tcl_Channel));
-    *outchannel = Tcl_CreateChannel(&RivetChan, "apacheout", &module_globals, TCL_WRITABLE);
-
-    /* The channel we have just created replaces Tcl's stdout */
-
-    Tcl_SetStdChannel (*outchannel, TCL_STDOUT);
 
-    /* Set the output buffer size to the largest allowed value, so that we 
-     * won't send any result packets to the browser unless the Rivet
-     * programmer does a "flush stdout" or the page is completed.
-     */
+        outchannel  = apr_pcalloc (pChild, sizeof(Tcl_Channel));
+        *outchannel = Tcl_CreateChannel(&RivetChan, "apacheout", rivet_thread_key, TCL_WRITABLE);
 
-    Tcl_SetChannelBufferSize (*outchannel, TCL_MAX_CHANNEL_BUFFER_SIZE);
+        /* The channel we have just created replaces Tcl's stdout */
 
-    module_globals.outchannel = outchannel;
+        Tcl_SetStdChannel (*outchannel, TCL_STDOUT);
 
-    for (i = 0; i < TCL_INTERPS; i++)
-    {
-        Tcl_Preserve (module_globals.interp_a[i]);
+        /* Set the output buffer size to the largest allowed value, so that we 
+         * won't send any result packets to the browser unless the Rivet
+         * programmer does a "flush stdout" or the page is completed.
+         */
 
-        /* We register the Tcl channel to the interpreter */
-
-        Tcl_RegisterChannel(module_globals.interp_a[i], *outchannel);
-        Tcl_Release (module_globals.interp_a[i]);
+        Tcl_SetChannelBufferSize (*outchannel, TCL_MAX_CHANNEL_BUFFER_SIZE);
+        module_globals.outchannel[i] = outchannel;
     }
+
     module_globals.interp_idx = 0;
-    module_globals.req = TclWeb_NewRequestObject (pChild);
 }
 
 static int RivetHandler(request_rec *r)
 {
-    Tcl_Interp* interp;
-    Tcl_Obj*    script = NULL;
-    int         interp_id;
-
+    Tcl_Interp*             interp;
+    Tcl_Obj*                script = NULL;
+    int                     interp_id;
+    rivet_thread_private*   private;
+    
     if (strcmp(r->handler, "application/x-httpd-rivet")) {
         return DECLINED;
     }
@@ -170,10 +161,17 @@ static int RivetHandler(request_rec *r)
     if (r->header_only) return OK;
     //if (r->args == 0) return OK;
 
-    interp_id = RivetFetchInterp(&interp,r);
+    /*
+    script = Tcl_NewStringObj("puts \"<html><head><title>experimental</title></head><body>OK</body></html>\"\n",-1);
+    */
+
+    /* */
+
+    interp_id = RivetFetchInterp(r);
+
+    interp = module_globals.interp_a[interp_id];
     Tcl_Preserve(module_globals.interp_a[interp_id]);
 
-    /*
     script = Tcl_NewStringObj("puts \"<html><head><title>experimental</title></head><body>OK</body></html>\"\n",-1);
     */
 
@@ -182,24 +180,44 @@ static int RivetHandler(request_rec *r)
     Tcl_AppendObjToObj(script,Tcl_NewIntObj(interp_id));
     Tcl_AppendStringsToObj(script,"\nputs \"</h2></body></html>\"",NULL);
 
-    apr_thread_mutex_lock(module_globals.channel_mutex);
 
-    Tcl_SetStdChannel (*(module_globals.outchannel), TCL_STDOUT);
+    if (apr_threadkey_private_get ((void **)&private,rivet_thread_key) != APR_SUCCESS)
+    {
+        RivetReleaseInterp(interp_id);
+        return DECLINED;
+
+    } else {
+
+        if (private == NULL)
+        {
+            apr_thread_mutex_lock(module_globals.channel_mutex);
+            private         = apr_palloc(module_globals.pool,sizeof(*private));
+            private->req    = TclWeb_NewRequestObject (module_globals.pool);
+            apr_thread_mutex_unlock(module_globals.channel_mutex);
+        }
+
+    }
+
+    private->interp  = module_globals.interp_a[interp_id];
+    private->channel = module_globals.outchannel[interp_id];
+    private->r       = r;
+    TclWeb_InitRequest(private->req,interp,r);
+    apr_threadkey_private_set (private,rivet_thread_key);
 
-    TclWeb_InitRequest(module_globals.req,interp,r);
-    module_globals.r = r;
+    Tcl_SetStdChannel (*(module_globals.outchannel[interp_id]), TCL_STDOUT);
 
+    apr_thread_mutex_lock(module_globals.channel_mutex);
     if (Tcl_EvalObjEx(interp, script, 0) == TCL_ERROR)
     {
         ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, r->server, 
                      "Error evaluating script: %s", Tcl_GetVar(interp, "errorInfo", 0));
     }
+    apr_thread_mutex_unlock(module_globals.channel_mutex);
 
-    TclWeb_PrintHeaders(module_globals.req);
-    Tcl_Flush(*(module_globals.outchannel));
+    TclWeb_PrintHeaders(private->req);
+    Tcl_Flush(*(module_globals.outchannel[interp_id]));
     Tcl_Release(module_globals.interp_a[interp_id]);
 
-    apr_thread_mutex_unlock(module_globals.channel_mutex);
     RivetReleaseInterp(interp_id);
 
     return OK;

Modified: tcl/rivet/trunk/src/experimental/mod_rivet.h
URL: http://svn.apache.org/viewvc/tcl/rivet/trunk/src/experimental/mod_rivet.h?rev=1611837&r1=1611836&r2=1611837&view=diff
==============================================================================
--- tcl/rivet/trunk/src/experimental/mod_rivet.h (original)
+++ tcl/rivet/trunk/src/experimental/mod_rivet.h Fri Jul 18 23:23:40 2014
@@ -133,11 +133,18 @@ typedef struct _mod_rivet_globals {
     int                 interp_idx;
     int                 busy_cnt;
     rivet_server_conf*  rsc_p;
-    request_rec*        r;			     /* request rec                 */
-    TclWebRequest*      req;
-    Tcl_Channel*        outchannel;		 /* stuff for buffering output  */
+    Tcl_Channel*        outchannel[TCL_INTERPS]; /* stuff for buffering output  */
 } mod_rivet_globals;
 
+typedef struct _thread_worker_private {
+
+    request_rec*        r;			    /* request rec                 */
+    TclWebRequest*      req;
+    Tcl_Interp*         interp;
+    Tcl_Channel*        channel;
+
+} rivet_thread_private;
+
 enum
 {
     idle,

Modified: tcl/rivet/trunk/src/experimental/rivetChannel.c
URL: http://svn.apache.org/viewvc/tcl/rivet/trunk/src/experimental/rivetChannel.c?rev=1611837&r1=1611836&r2=1611837&view=diff
==============================================================================
--- tcl/rivet/trunk/src/experimental/rivetChannel.c (original)
+++ tcl/rivet/trunk/src/experimental/rivetChannel.c Fri Jul 18 23:23:40 2014
@@ -19,6 +19,9 @@
 #ifdef HAVE_CONFIG_H
 #include <rivet_config.h>
 #endif
+#include <apr_general.h>
+#include <apr_thread_proc.h>
+#include <apr_thread_cond.h>
 
 #include "httpd.h"
 #include "http_config.h"
@@ -43,14 +46,18 @@ inputproc(ClientData instancedata, char 
 static int
 outputproc(ClientData instancedata, CONST84 char *buf, int toWrite, int *errorCodePtr)
 {
-    mod_rivet_globals* globals = (mod_rivet_globals *)instancedata;
+    apr_threadkey_t*        rivet_thread_key = (apr_threadkey_t*) instancedata;
+    rivet_thread_private*   private;
+    
+    apr_threadkey_private_get ((void **)&private,rivet_thread_key);
 
-    TclWeb_PrintHeaders(globals->req);
-    if (globals->req->content_sent == 0)
+    TclWeb_PrintHeaders(private->req);
+    if (private->req->content_sent == 0)
     {
-        ap_rwrite(buf, toWrite, globals->r);
-        ap_rflush(globals->r);
+        ap_rwrite(buf, toWrite, private->r);
+        ap_rflush(private->r);
     }
+
     return toWrite;
 }
 



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