You are viewing a plain text version of this content. The canonical link for it is here.
Posted to rivet-dev@tcl.apache.org by da...@apache.org on 2002/03/13 07:51:18 UTC

cvs commit: tcl-rivet/src TclWebapache.c mod_rivet.c mod_rivet.h rivetCore.c rivetParser.c

damonc      02/03/12 22:51:18

  Modified:    .        ChangeLog
               src      TclWebapache.c mod_rivet.c mod_rivet.h rivetCore.c
                        rivetParser.c
  Log:
  * src/mod_rivet.c
  * src/mod_rivet.h
  * src/rivetParser.c
  * src/rivetCore.c
  * src/TclWebapache.c
      Cleaned up a lot of memory leaks.  Still working on finding more.
  
  Revision  Changes    Path
  1.38      +9 -0      tcl-rivet/ChangeLog
  
  Index: ChangeLog
  ===================================================================
  RCS file: /home/cvs/tcl-rivet/ChangeLog,v
  retrieving revision 1.37
  retrieving revision 1.38
  diff -u -r1.37 -r1.38
  --- ChangeLog	12 Mar 2002 06:51:57 -0000	1.37
  +++ ChangeLog	13 Mar 2002 06:51:18 -0000	1.38
  @@ -1,3 +1,12 @@
  +2002-03-12  Damon J. Courtney <da...@unreality.com>
  +
  +	* src/mod_rivet.c
  +	* src/mod_rivet.h
  +	* src/rivetParser.c
  +	* src/rivetCore.c
  +	* src/TclWebapache.c
  +	    Cleaned up a lot of memory leaks.  Still working on finding more.
  +
   2002-03-11  Damon J. Courtney <da...@unreality.com>
   
   	* src/TclWeb.h
  
  
  
  1.16      +1 -5      tcl-rivet/src/TclWebapache.c
  
  Index: TclWebapache.c
  ===================================================================
  RCS file: /home/cvs/tcl-rivet/src/TclWebapache.c,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- TclWebapache.c	12 Mar 2002 16:57:24 -0000	1.15
  +++ TclWebapache.c	13 Mar 2002 06:51:18 -0000	1.16
  @@ -7,7 +7,7 @@
    * operations.
    */
   
  -/* $Id: TclWebapache.c,v 1.15 2002/03/12 16:57:24 davidw Exp $ */
  +/* $Id: TclWebapache.c,v 1.16 2002/03/13 06:51:18 damonc Exp $ */
   
   #include <tcl.h>
   
  @@ -146,7 +146,6 @@
   		flag = 1;
   		Tcl_SetStringObj(result,
   				 TclWeb_StringToUtf(parms[i].val, req), -1);
  -		Tcl_IncrRefCount(result);
   	    } else {
   		Tcl_Obj *tmpobj;
   		Tcl_Obj *tmpobjv[2];
  @@ -247,12 +246,10 @@
   	if (!strncmp(varname, TclWeb_StringToUtf(parms[i].key, req), strlen(varname)))
   	{
   	    Tcl_SetIntObj(result, 1);
  -	    Tcl_IncrRefCount(result);
   	    return TCL_OK;
   	}
       }
       Tcl_SetIntObj(result, 0);
  -    Tcl_IncrRefCount(result);
       return TCL_OK;
   }
   
  @@ -262,7 +259,6 @@
       array_header *parmsarray = ap_table_elts(req->apachereq->parms);
   
       Tcl_SetIntObj(result, parmsarray->nelts);
  -    Tcl_IncrRefCount(result);
       return TCL_OK;
   }
   
  
  
  
  1.35      +32 -16    tcl-rivet/src/mod_rivet.c
  
  Index: mod_rivet.c
  ===================================================================
  RCS file: /home/cvs/tcl-rivet/src/mod_rivet.c,v
  retrieving revision 1.34
  retrieving revision 1.35
  diff -u -r1.34 -r1.35
  --- mod_rivet.c	12 Mar 2002 06:51:57 -0000	1.34
  +++ mod_rivet.c	13 Mar 2002 06:51:18 -0000	1.35
  @@ -55,7 +55,7 @@
    * originally written at the National Center for Supercomputing Applications,
    * University of Illinois, Urbana-Champaign.  */
   
  -/* $Id: mod_rivet.c,v 1.34 2002/03/12 06:51:57 damonc Exp $  */
  +/* $Id: mod_rivet.c,v 1.35 2002/03/13 06:51:18 damonc Exp $  */
   
   /* mod_rivet.c by David Welton <da...@apache.org>
    *            and Damon Courtney <da...@unreality.com>
  @@ -86,7 +86,6 @@
   #include "rivet.h"
   #include "rivetParser.h"
   
  -
   module MODULE_VAR_EXPORT rivet_module;
   
   /* Need some arbitrary non-NULL pointer which can't also be a request_rec */
  @@ -219,7 +218,6 @@
       {
   
   	outbuf = Tcl_NewObj();
  -	Tcl_IncrRefCount(outbuf);
   	if (toplevel && rsc->rivet_before_script) {
   	    Tcl_AppendObjToObj(outbuf, rsc->rivet_before_script);
   	}
  @@ -242,6 +240,11 @@
   	}
   
   	if (*(rsc->cache_size)) {
  +	    /* We need to incr the reference count of outbuf because we want
  +	     * it to outlive this function.  This allows it to stay alive
  +	     * as long as it's in the object cache. 
  +	     */
  +	    Tcl_IncrRefCount( outbuf );
   	    Tcl_SetHashValue(entry, (ClientData)outbuf);
   	}
   
  @@ -259,6 +262,7 @@
   		    sizeof(char *) * (*(rsc->cache_size) -1));
   	    rsc->objCacheList[0] = strdup(hashKey);
   	}
  +
       } else {
   	/* We found a compiled version of this page. */
   	outbuf = (Tcl_Obj *)Tcl_GetHashValue(entry);
  @@ -268,6 +272,22 @@
   }
   
   static void
  +Rivet_CleanupRequest( request_rec *r )
  +{
  +    rivet_server_conf *rdc = RIVET_SERVER_CONF( r->per_dir_config );
  +
  +    if( rdc->rivet_before_script ) {
  +	Tcl_DecrRefCount( rdc->rivet_before_script );
  +    }
  +    if( rdc->rivet_after_script ) {
  +	Tcl_DecrRefCount( rdc->rivet_after_script );
  +    }
  +    if( rdc->rivet_error_script ) {
  +	Tcl_DecrRefCount( rdc->rivet_error_script );
  +    }
  +}
  +
  +static void
   Rivet_PropagatePerDirConfArrays( Tcl_Interp *interp, rivet_server_conf *rsc )
   {
       table *t;
  @@ -324,7 +344,9 @@
       char timefmt[MAX_STRING_LEN];
       int errstatus;
   
  -    Tcl_Interp *interp;
  +    Tcl_Interp	*interp;
  +    Tcl_Obj	*request_init;
  +    Tcl_Obj	*request_cleanup;
   
       rivet_interp_globals *globals = NULL;
       rivet_server_conf *rsc = NULL;
  @@ -362,7 +384,8 @@
   
       Rivet_PropagatePerDirConfArrays( interp, rdc );
   
  -    if (Tcl_EvalObj(interp, rsc->request_init) == TCL_ERROR)
  +    request_init = Tcl_NewStringObj("::Rivet::initialize_request\n",-1);
  +    if (Tcl_EvalObj(interp, request_init) == TCL_ERROR)
       {
   	ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
   			"Could not create request namespace\n");
  @@ -399,7 +422,8 @@
   		     Tcl_GetVar(interp, "errorInfo", 0));
       }
   
  -    if(Tcl_EvalObj(interp, rsc->request_cleanup) == TCL_ERROR) {
  +    request_cleanup = Tcl_NewStringObj("::Rivet::cleanup_request\n",-1);
  +    if(Tcl_EvalObj(interp, request_cleanup) == TCL_ERROR) {
   	ap_log_error(APLOG_MARK, APLOG_ERR, r->server, "%s",
   		     Tcl_GetVar(interp, "errorInfo", 0));
       }
  @@ -407,6 +431,8 @@
       /* Reset globals */
       globals->req->content_sent = 0;
   
  +    Rivet_CleanupRequest( r );
  +
       return OK;
   }
   
  @@ -521,12 +547,6 @@
   	exit(1);
       }
   
  -    rsc->request_init = Tcl_NewStringObj("::Rivet::initialize_request\n",-1);
  -    Tcl_IncrRefCount(rsc->request_init);
  -
  -    rsc->request_cleanup = Tcl_NewStringObj("::Rivet::cleanup_request\n",-1);
  -    Tcl_IncrRefCount(rsc->request_cleanup);
  -
       if (rsc->rivet_global_init_script != NULL)
       {
   	rslt = Tcl_EvalObjEx(interp, rsc->rivet_global_init_script, 0);
  @@ -841,8 +861,6 @@
       newrsc->upload_dir = oldrsc->upload_dir;
       newrsc->objCacheList = oldrsc->objCacheList;
       newrsc->objCache = oldrsc->objCache;
  -    newrsc->request_init = oldrsc->request_init;
  -    newrsc->request_cleanup = oldrsc->request_cleanup;
   
       newrsc->outchannel = oldrsc->outchannel;
   }
  @@ -872,8 +890,6 @@
       rsc->upload_dir = "/tmp";
       rsc->objCacheList = NULL;
       rsc->objCache = ap_pcalloc(p, sizeof(Tcl_HashTable));
  -    rsc->request_init = NULL;
  -    rsc->request_cleanup = NULL;
   
       rsc->outchannel = ap_pcalloc(p, sizeof(Tcl_Channel));
   
  
  
  
  1.18      +0 -3      tcl-rivet/src/mod_rivet.h
  
  Index: mod_rivet.h
  ===================================================================
  RCS file: /home/cvs/tcl-rivet/src/mod_rivet.h,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- mod_rivet.h	12 Feb 2002 11:09:58 -0000	1.17
  +++ mod_rivet.h	13 Mar 2002 06:51:18 -0000	1.18
  @@ -57,9 +57,6 @@
       char **objCacheList;   /* Array of cached objects (for priority handling) */
       Tcl_HashTable *objCache; /* Objects cache - the key is the script name */
   
  -    Tcl_Obj *request_init; /* initial bit of Tcl for namespace creation */
  -    Tcl_Obj *request_cleanup; /* bit of Tcl for cleaning up after a request */
  -
       /* stuff for buffering output */
       Tcl_Channel *outchannel;
   } rivet_server_conf;
  
  
  
  1.19      +1 -10     tcl-rivet/src/rivetCore.c
  
  Index: rivetCore.c
  ===================================================================
  RCS file: /home/cvs/tcl-rivet/src/rivetCore.c,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- rivetCore.c	12 Mar 2002 16:57:24 -0000	1.18
  +++ rivetCore.c	13 Mar 2002 06:51:18 -0000	1.19
  @@ -2,7 +2,7 @@
    * rivetCore.c - Core commands which are compiled into mod_rivet itself.
    */
   
  -/* $Id: rivetCore.c,v 1.18 2002/03/12 16:57:24 davidw Exp $ */
  +/* $Id: rivetCore.c,v 1.19 2002/03/13 06:51:18 damonc Exp $ */
   
   #include "httpd.h"
   #include "http_config.h"
  @@ -119,16 +119,13 @@
       Tcl_SetChannelOption(interp, fd, "-translation", "binary");
   
       outobj = Tcl_NewObj();
  -    Tcl_IncrRefCount(outobj);
       sz = Tcl_ReadChars(fd, outobj, -1, 0);
       if (sz == -1)
       {
   	Tcl_AddErrorInfo(interp, Tcl_PosixError(interp));
  -	Tcl_DecrRefCount(outobj);
   	return TCL_ERROR;
       }
       Tcl_WriteObj(Tcl_GetChannel(interp, "stdout", NULL), outobj);
  -    Tcl_DecrRefCount(outobj);
       return Tcl_Close(interp, fd);
   }
   
  @@ -264,8 +261,6 @@
   	ArrayObj = Tcl_NewStringObj( ENV_ARRAY_NAME, -1 );
       }
   
  -    Tcl_IncrRefCount( ArrayObj );
  -
       return TclWeb_GetEnvVars(ArrayObj, globals->req);
   }
   
  @@ -337,7 +332,6 @@
   	if (TclWeb_GetVar(result, key, globals->req) != TCL_OK)
   	{
   	    result = Tcl_NewStringObj("", -1);
  -	    Tcl_IncrRefCount(result);
   	}
       } else if(!strcmp(command, "exists")) {
   	char *key;
  @@ -361,7 +355,6 @@
   	if (TclWeb_GetVarAsList(result, key, globals->req) != TCL_OK)
   	{
   	    result = Tcl_NewStringObj("", -1);
  -	    Tcl_IncrRefCount(result);
   	}
       } else if(!strcmp(command, "names")) {
   	if (objc != 2)
  @@ -373,7 +366,6 @@
   	if (TclWeb_GetVarNames(result, globals->req) != TCL_OK)
   	{
   	    result = Tcl_NewStringObj("", -1);
  -	    Tcl_IncrRefCount(result);
   	}
       } else if(!strcmp(command, "number")) {
   	if (objc != 2)
  @@ -392,7 +384,6 @@
   	if (TclWeb_GetAllVars(result, globals->req) != TCL_OK)
   	{
   	    result = Tcl_NewStringObj("", -1);
  -	    Tcl_IncrRefCount(result);
   	}
       } else {
   	/* bad command  */
  
  
  
  1.4       +1 -3      tcl-rivet/src/rivetParser.c
  
  Index: rivetParser.c
  ===================================================================
  RCS file: /home/cvs/tcl-rivet/src/rivetParser.c,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- rivetParser.c	11 Mar 2002 00:31:10 -0000	1.3
  +++ rivetParser.c	13 Mar 2002 06:51:18 -0000	1.4
  @@ -6,7 +6,7 @@
    *
    */
   
  -/* $Id: rivetParser.c,v 1.3 2002/03/11 00:31:10 damonc Exp $ */
  +/* $Id: rivetParser.c,v 1.4 2002/03/13 06:51:18 damonc Exp $ */
   
   #include <tcl.h>
   #include "mod_rivet.h"
  @@ -94,14 +94,12 @@
       Tcl_AppendToObj(outbuf, "puts -nonewline \"", -1);
   
       inbuf = Tcl_NewObj();
  -    Tcl_IncrRefCount(inbuf);
       sz = Tcl_ReadChars(rivetfile, inbuf, -1, 0);
   
       Tcl_Close(req->interp, rivetfile);
       if (sz == -1)
       {
   	Tcl_AddErrorInfo(req->interp, Tcl_PosixError(req->interp));
  -	Tcl_DecrRefCount(inbuf);
   	return TCL_ERROR;
       }
   
  
  
  

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


Re: cvs commit: tcl-rivet/src TclWebapache.c mod_rivet.c mod_rivet.h rivetCore.c rivetParser.c

Posted by Damon Courtney <da...@your.unreality.com>.
> Damon Courtney <da...@your.unreality.com> writes:
> 
> > > I keep thinking about it, but I really do want to preserve the
> > > per-directory stuff in some way.
> 
> >     I do too.  I think the best way to do this, since the user
> > directives are meant to be very limited, is to just add variables
> > special to the user directives... IE:
> 
> > rsc->rivet_user_before_script
> > rsc->rivet_user_after_script
> > rsc->rivet_user_error_script
> 
> >     Then, we can always make sure those get freed after the request.
> > While the directory directives will be set as normal.  We'd have to
> > decide how we wanna' do it though.  Do we want user-level directives
> > to overwrite the directory level actions?  As it stands now, there's
> > a heirarchy.
> 
> >     Server directives -> Directory directives -> User directives.
> > If any one exists further down the line, it overwrites the previous
> > level.  I think this is a good way to go.  It's not tough though.
> > What do you think?
> 
> Ok, with error_script, this makes sense.  "There can be only one", and
> all that.
> 
> However, I wonder if it would ever be useful for people to have
> before/after scripts that append (or prepend!) something to the global
> before/after script...

    Well, I gave that a lot of thought.  I think it would be cool, but I
think that in most cases, the only reason you'd want to use a User-level
before script is to overwrite the default Directory case.

    I mean, I use UserConf for testing stuff and development, but once
it's thoroughly tested, it's WAY cheaper to put them httpd.conf than
keep them in a .htaccess file.  First of all, you can then turn off
AllowOverride, which will make requests faster since they're not checking
every directory in the tree for a .htaccess file.  And, your scripts aren't
being reloaded every single page.

    So, I can imagine the only reason you might want to user the UserConf
directive for these scripts IS specifically to override the default
directory behavior.

    If we're gonna' do it this way, we need some way of clearing the
current script.  Like:

RivetUserConf BeforeScript reset
RivetUserConf "New script here"

    Something like that.

D


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


Re: cvs commit: tcl-rivet/src TclWebapache.c mod_rivet.c mod_rivet.h rivetCore.c rivetParser.c

Posted by "David N. Welton" <da...@dedasys.com>.
Damon Courtney <da...@your.unreality.com> writes:

> > I keep thinking about it, but I really do want to preserve the
> > per-directory stuff in some way.

>     I do too.  I think the best way to do this, since the user
> directives are meant to be very limited, is to just add variables
> special to the user directives... IE:

> rsc->rivet_user_before_script
> rsc->rivet_user_after_script
> rsc->rivet_user_error_script

>     Then, we can always make sure those get freed after the request.
> While the directory directives will be set as normal.  We'd have to
> decide how we wanna' do it though.  Do we want user-level directives
> to overwrite the directory level actions?  As it stands now, there's
> a heirarchy.

>     Server directives -> Directory directives -> User directives.
> If any one exists further down the line, it overwrites the previous
> level.  I think this is a good way to go.  It's not tough though.
> What do you think?

Ok, with error_script, this makes sense.  "There can be only one", and
all that.

However, I wonder if it would ever be useful for people to have
before/after scripts that append (or prepend!) something to the global
before/after script...

-- 
David N. Welton
   Consulting: http://www.dedasys.com/
     Personal: http://www.dedasys.com/davidw/
Free Software: http://www.dedasys.com/freesoftware/
   Apache Tcl: http://tcl.apache.org/

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


Re: cvs commit: tcl-rivet/src TclWebapache.c mod_rivet.c mod_rivet.h rivetCore.c rivetParser.c

Posted by Damon Courtney <da...@your.unreality.com>.
> > > >     Any thoughts?
> 
> > > Yes - I hate this conf shit.  It is no end of headaches.
> 
> >     Well, we can certainly take it all out. 0-] There is one really
> > good way to do it, though I still think using Apache is more to most
> > peoples' liking.  The only other way to go is it use an AOLServer
> > style configuration.  Since AOLServer is all Tcl, there
> > configuration is all Tcl.
> 
> I keep thinking about it, but I really do want to preserve the
> per-directory stuff in some way.

    I do too.  I think the best way to do this, since the user directives
are meant to be very limited, is to just add variables special to the
user directives... IE:

rsc->rivet_user_before_script
rsc->rivet_user_after_script
rsc->rivet_user_error_script

    Then, we can always make sure those get freed after the request.
While the directory directives will be set as normal.  We'd have to decide
how we wanna' do it though.  Do we want user-level directives to overwrite
the directory level actions?  As it stands now, there's a heirarchy.

    Server directives -> Directory directives -> User directives.  If
any one exists further down the line, it overwrites the previous level.
I think this is a good way to go.  It's not tough though.  What do you
think?

D


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


Re: Global

Posted by "David N. Welton" <da...@dedasys.com>.
Damon Courtney <da...@your.unreality.com> writes:

>     I'll give you a better example.  I ran into this while
> developing a project the other day, and I had to completely re-write
> the way I was doing things because of this limitation.

>     I create a namespace for my procedures.  I plan to put in a
> really slick packaging system for Rivet with each package in its own
> namespace.  So, we have:

> namespace eval ::some_package {

> }

>     See a problem?  Most packages create themselves relative to the
> global namespace.  This will become a problem when they use
> variables within their namespace.  Why?  Because that namespace will
> never be destroyed with the rest.  So, the next time a page loads,
> variables already exist that are from last time.  Bad juju.

>     Now, if we make the global command OUR global command, we just
> write all packages with global's instead of variable's, and it

So, we would have to rewrite packages to work with Rivet?

The ultimate goal is to make sure that people can take Tcl code and
"just use it" - or at least I think that's what we should aim for.

> ensures that all variables are kept within the ::request namespace.
> Very rarely should there ever be a case when a user needs the REAL
> global command.  And even if they did, 'upvar #0' works as a nice
> substitute. 0-]

-- 
David N. Welton
   Consulting: http://www.dedasys.com/
     Personal: http://www.dedasys.com/davidw/
Free Software: http://www.dedasys.com/freesoftware/
   Apache Tcl: http://tcl.apache.org/

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


Re: Global

Posted by Damon Courtney <da...@your.unreality.com>.
> Damon Courtney <da...@your.unreality.com> writes:
> 
> >     The commands I'm using aren't written in the ::request
> > namespace.  We don't want to have to reload all of Rivet's commands
> > everytime a request comes in, so we create the procs in the global
> > namespace.  But, occassionally, I want to load global variables, and
> > they actually do get loaded in stack #0.  Then, when ::request is
> > destroyed, they still hang around, and can cause really spurious
> > errors later on.
> 
> My original thinking with that bit of code was this:
> 
> I wanted to be able to run Tcl scripts with as little changes as
> possible in mod_dtcl, and 'global' was obviously causing some
> problems.  "variable" actually makes more sense, but that requires
> modification of the script.
> 
> It's possible, of course, to just use ::global, as that's still the
> real thing.
> 
> And, to discuss the earlier comment... hrm, instead of upvar'ing,
> wouldn't it be more explicit to just refer to ::request::foo ?

    I'll give you a better example.  I ran into this while developing
a project the other day, and I had to completely re-write the way I was
doing things because of this limitation.

    I create a namespace for my procedures.  I plan to put in a really
slick packaging system for Rivet with each package in its own namespace.
So, we have:

namespace eval ::some_package {

}

    See a problem?  Most packages create themselves relative to the
global namespace.  This will become a problem when they use variables
within their namespace.  Why?  Because that namespace will never be
destroyed with the rest.  So, the next time a page loads, variables
already exist that are from last time.  Bad juju.

    Now, if we make the global command OUR global command, we just write
all packages with global's instead of variable's, and it ensures that all
variables are kept within the ::request namespace.  Very rarely should
there ever be a case when a user needs the REAL global command.  And even
if they did, 'upvar #0' works as a nice substitute. 0-]

D


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


Re: Global

Posted by "David N. Welton" <da...@dedasys.com>.
Damon Courtney <da...@your.unreality.com> writes:

>     The commands I'm using aren't written in the ::request
> namespace.  We don't want to have to reload all of Rivet's commands
> everytime a request comes in, so we create the procs in the global
> namespace.  But, occassionally, I want to load global variables, and
> they actually do get loaded in stack #0.  Then, when ::request is
> destroyed, they still hang around, and can cause really spurious
> errors later on.

My original thinking with that bit of code was this:

I wanted to be able to run Tcl scripts with as little changes as
possible in mod_dtcl, and 'global' was obviously causing some
problems.  "variable" actually makes more sense, but that requires
modification of the script.

It's possible, of course, to just use ::global, as that's still the
real thing.

And, to discuss the earlier comment... hrm, instead of upvar'ing,
wouldn't it be more explicit to just refer to ::request::foo ?

-- 
David N. Welton
   Consulting: http://www.dedasys.com/
     Personal: http://www.dedasys.com/davidw/
Free Software: http://www.dedasys.com/freesoftware/
   Apache Tcl: http://tcl.apache.org/

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


Re: Global

Posted by Wojciech Kocjan <wo...@kocjan.org>.
Damon Courtney wrote:
>     Oh, I know the variable command well.  I do most of my programming
> in namespaces to avoid collusion, but that doesn't help me here.  The
> commands I'm creating are in the global namespace.  If I use the variable
> command from the global namespace, it's just like using the global command.

Hmmm.

I suppose you should just make another function - like rglobal (from 
request global). I sometimes used global when I shared data across 
namespaces - mostly in code loaded at startup.

I suppose it could mislead some people who know exactly how does global 
work.

I suppose it should be a separate command and it should be mentioned in 
the docs - so that new users do not get confused about global.

>     The commands I'm using aren't written in the ::request namespace.
> We don't want to have to reload all of Rivet's commands everytime a
> request comes in, so we create the procs in the global namespace.  But,
> occassionally, I want to load global variables, and they actually do get
> loaded in stack #0.  Then, when ::request is destroyed, they still hang
> around, and can cause really spurious errors later on.

proc hglobal {args} {
     foreach v $args {
         uplevel [list upvar #0 ::request::$v $v]
     }
}

proc hvar {args} {
     set n ::request::[uplevel {namespace current}]
     namespace eval $n {}
     foreach v $args {
         uplevel [list upvar #0 ${n}::$v $v]
     }
}

The second one would create connection&namespace specific variables...
--
WK


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


Re: Global

Posted by Damon Courtney <da...@your.unreality.com>.
> Why not just use 'variable' instead of global?
> 
> -- SNIP --
> If the variable command is executed inside a Tcl procedure, it creates 
> local variables linked to the corresponding namespace variables. In this 
> way the variable command resembles the global command, although the 
> global command only links to variables in the global namespace.
> -- SNIP --

    Oh, I know the variable command well.  I do most of my programming
in namespaces to avoid collusion, but that doesn't help me here.  The
commands I'm creating are in the global namespace.  If I use the variable
command from the global namespace, it's just like using the global command.

    The commands I'm using aren't written in the ::request namespace.
We don't want to have to reload all of Rivet's commands everytime a
request comes in, so we create the procs in the global namespace.  But,
occassionally, I want to load global variables, and they actually do get
loaded in stack #0.  Then, when ::request is destroyed, they still hang
around, and can cause really spurious errors later on.

D


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


Re: Global

Posted by Wojciech Kocjan <wo...@kocjan.org>.
Why not just use 'variable' instead of global?

-- SNIP --
If the variable command is executed inside a Tcl procedure, it creates 
local variables linked to the corresponding namespace variables. In this 
way the variable command resembles the global command, although the 
global command only links to variables in the global namespace.
-- SNIP --

A small example:

namespace eval x {
     proc y {} {
         variable z
         incr z
         return $z
     }
     set z 0
}

% x::y
1
% x::y
2
% x::y
3

When I write a script/engine, I do the following:

namespace eval somename {}

proc somename::someproc {} {
     variable d
     set d(something) [something]
}

It's much easier and nicer to use namespace local variables :>

--
WK


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


Global

Posted by Damon Courtney <da...@your.unreality.com>.
Ok,

    I've been thinking about this a bit, and I'm thinking we should
really rename the global command on the global level.  IE: Instead of just
defining a global proc within the ::request namespace, we should define
that same proc in the :: namespace and make server-wide.

    My problem is this.  Everytime I write a proc of some kind to go in
the server, I have to upvar into the ::request namespace in order to keep
the variables localized.  Here's what I propose:

rename global trueGlobal

    And then, add an option to the global proc that says if the first
argument is "-true," it executes the true global command instead of
using the namespace.  Something like that anyway.

D


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


Re: cvs commit: tcl-rivet/src TclWebapache.c mod_rivet.c mod_rivet.h rivetCore.c rivetParser.c

Posted by "David N. Welton" <da...@dedasys.com>.
Damon Courtney <da...@your.unreality.com> writes:

> > >     Any thoughts?

> > Yes - I hate this conf shit.  It is no end of headaches.

>     Well, we can certainly take it all out. 0-] There is one really
> good way to do it, though I still think using Apache is more to most
> peoples' liking.  The only other way to go is it use an AOLServer
> style configuration.  Since AOLServer is all Tcl, there
> configuration is all Tcl.

I keep thinking about it, but I really do want to preserve the
per-directory stuff in some way.

-- 
David N. Welton
   Consulting: http://www.dedasys.com/
     Personal: http://www.dedasys.com/davidw/
Free Software: http://www.dedasys.com/freesoftware/
   Apache Tcl: http://tcl.apache.org/

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


Re: cvs commit: tcl-rivet/src TclWebapache.c mod_rivet.c mod_rivet.h rivetCore.c rivetParser.c

Posted by Damon Courtney <da...@your.unreality.com>.
> >     Any thoughts?
> 
> Yes - I hate this conf shit.  It is no end of headaches.

    Well, we can certainly take it all out. 0-]  There is one really
good way to do it, though I still think using Apache is more to most
peoples' liking.  The only other way to go is it use an AOLServer style
configuration.  Since AOLServer is all Tcl, there configuration is all
Tcl.

    We could easily add in a config.tcl in the rivet directory that is
the first thing sourced and sets up the options for the rest of the
server.  We could make it XML-style like Apache, or we could just have
them set the variables within the arrays.

    Since the only ones we really need to get at the C level are Server
and Dir Conf directives (*Script can be executed at the Tcl-level with
an eval instead of how we're doing it now), we can just grab those
variables from Tcl at start-up of the server and save them in the
configuration.

    Just a thought.  It's not impossible.  Most Tcl programmers might
actually appreciate it.  I know I liked it as a feature of AOLServer.

    We might consider doing this on top of what we already have.  I
think if we could do configuration at the Tcl level, we easily take
care of a lot these configuration merger problems.

> BTW, while we're on that topic, do we really need to be doing the
> merging in GetConf?  I had that in there for dtcl, but maybe just
> because I didn't have the right setup, and was doing things there
> instead of the directory merger...

    I'm not sure.  I can look into the GetConf thing.

D


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


Re: cvs commit: tcl-rivet/src TclWebapache.c mod_rivet.c mod_rivet.h rivetCore.c rivetParser.c

Posted by "David N. Welton" <da...@dedasys.com>.
Damon Courtney <da...@your.unreality.com> writes:

>     Any thoughts?

Yes - I hate this conf shit.  It is no end of headaches.

BTW, while we're on that topic, do we really need to be doing the
merging in GetConf?  I had that in there for dtcl, but maybe just
because I didn't have the right setup, and was doing things there
instead of the directory merger...

> > >    static void
> > >   +Rivet_CleanupRequest( request_rec *r )
> > >   +{
> > >   +    rivet_server_conf *rdc = RIVET_SERVER_CONF( r->per_dir_config );
> > >   +
> > >   +    if( rdc->rivet_before_script ) {
> > >   +	Tcl_DecrRefCount( rdc->rivet_before_script );
> > >   +    }
> > >   +    if( rdc->rivet_after_script ) {
> > >   +	Tcl_DecrRefCount( rdc->rivet_after_script );
> > >   +    }
> > >   +    if( rdc->rivet_error_script ) {
> > >   +	Tcl_DecrRefCount( rdc->rivet_error_script );
> > >   +    }
> > >   +}

> > What's up with this?  These things need to stay around...

> > >   +    request_init = Tcl_NewStringObj("::Rivet::initialize_request\n",-1);
> > >   +    if (Tcl_EvalObj(interp, request_init) == TCL_ERROR)

> > These will slow us down, and I don't see them as a memory leak.  I
> > mean, they just hang around...

>     Well, my understanding of Apache server configuration was
> somewhat mislead.  I agree that this is the wrong thing to do, but
> I'm still working on the problem.  Directory directives just hang
> around for the life of the server.  User directives, however, keep
> getting created.

>     In the case of Server and Dir Conf directives, they are only
> executed once: at start-up.  UserConf directives, however, are
> executed everytime a page loads.  This is causing our biggest memory
> leaks.  Everytime you do:

> RivetUserConf BeforeScript "do something"

>     You're creating a new Tcl object for that script that never gets
> freed.  I agree that we need to keep around the directory
> directives.  I think I just need to splice them out a little, so
> that user directives are a separate entity.  They need to be freed
> after each request.  Still not sure about what approach I'll take
> though.

Ok, I see your point.  I'll look at it from that point of view.

-- 
David N. Welton
   Consulting: http://www.dedasys.com/
     Personal: http://www.dedasys.com/davidw/
Free Software: http://www.dedasys.com/freesoftware/
   Apache Tcl: http://tcl.apache.org/

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


Re: cvs commit: tcl-rivet/src TclWebapache.c mod_rivet.c mod_rivet.h rivetCore.c rivetParser.c

Posted by Damon Courtney <da...@your.unreality.com>.
> >    static void
> >   +Rivet_CleanupRequest( request_rec *r )
> >   +{
> >   +    rivet_server_conf *rdc = RIVET_SERVER_CONF( r->per_dir_config );
> >   +
> >   +    if( rdc->rivet_before_script ) {
> >   +	Tcl_DecrRefCount( rdc->rivet_before_script );
> >   +    }
> >   +    if( rdc->rivet_after_script ) {
> >   +	Tcl_DecrRefCount( rdc->rivet_after_script );
> >   +    }
> >   +    if( rdc->rivet_error_script ) {
> >   +	Tcl_DecrRefCount( rdc->rivet_error_script );
> >   +    }
> >   +}
> 
> What's up with this?  These things need to stay around...
> 
> >   +    request_init = Tcl_NewStringObj("::Rivet::initialize_request\n",-1);
> >   +    if (Tcl_EvalObj(interp, request_init) == TCL_ERROR)
> 
> These will slow us down, and I don't see them as a memory leak.  I
> mean, they just hang around...

    Well, my understanding of Apache server configuration was somewhat
mislead.  I agree that this is the wrong thing to do, but I'm still working
on the problem.  Directory directives just hang around for the life of the
server.  User directives, however, keep getting created.

    In the case of Server and Dir Conf directives, they are only executed
once: at start-up.  UserConf directives, however, are executed everytime
a page loads.  This is causing our biggest memory leaks.  Everytime you do:

RivetUserConf BeforeScript "do something"

    You're creating a new Tcl object for that script that never gets
freed.  I agree that we need to keep around the directory directives.
I think I just need to splice them out a little, so that user directives
are a separate entity.  They need to be freed after each request.  Still
not sure about what approach I'll take though.

    Any thoughts?

D


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


Re: cvs commit: tcl-rivet/src TclWebapache.c mod_rivet.c mod_rivet.h rivetCore.c rivetParser.c

Posted by "David N. Welton" <da...@dedasys.com>.
damonc@apache.org writes:

>    static void
>   +Rivet_CleanupRequest( request_rec *r )
>   +{
>   +    rivet_server_conf *rdc = RIVET_SERVER_CONF( r->per_dir_config );
>   +
>   +    if( rdc->rivet_before_script ) {
>   +	Tcl_DecrRefCount( rdc->rivet_before_script );
>   +    }
>   +    if( rdc->rivet_after_script ) {
>   +	Tcl_DecrRefCount( rdc->rivet_after_script );
>   +    }
>   +    if( rdc->rivet_error_script ) {
>   +	Tcl_DecrRefCount( rdc->rivet_error_script );
>   +    }
>   +}

What's up with this?  These things need to stay around...

>   +    request_init = Tcl_NewStringObj("::Rivet::initialize_request\n",-1);
>   +    if (Tcl_EvalObj(interp, request_init) == TCL_ERROR)

These will slow us down, and I don't see them as a memory leak.  I
mean, they just hang around...

-- 
David N. Welton
   Consulting: http://www.dedasys.com/
     Personal: http://www.dedasys.com/davidw/
Free Software: http://www.dedasys.com/freesoftware/
   Apache Tcl: http://tcl.apache.org/

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