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