Re: [AOLSERVER] nsv API in C ?
On 2002.05.04, Andrew Piskorski <[EMAIL PROTECTED]> wrote: > I haven't studied the tclvar.c much, but why would nsv locks have > anything to do with threads at all? The nsv data structures are > server-wide, after all, so I don't THINK there's anything per-thread > or per-interp about them at all. When you go to update an nsv, you need exclusive access to the nsv you're updating. So, you need an exlusive lock that only grants your interp in your thread to update it, preventing other threads and other interps from doing so. Makes sense to me ... I could be wrong. -- Dossy -- Dossy Shiobara mail: [EMAIL PROTECTED] Panoptic Computer Network web: http://www.panoptic.com/ "He realized the fastest way to change is to laugh at your own folly -- then you can let go and quickly move on." (p. 70)
Re: [AOLSERVER] nsv API in C ?
On Sat, May 04, 2002 at 11:06:09AM -0400, Dossy wrote: > On 2002.05.04, Andrew Piskorski <[EMAIL PROTECTED]> wrote: > > On Sat, May 04, 2002 at 01:31:42AM -0400, Dossy wrote: > If you're not passing the interp to Ns_TclEval to tell it in which > interpreter to perform the TclEval ... then don't you wonder which > interp it's using? Um... I admit that never occurred to me. Ah, Ns_TclEval calls Ns_TclAllocateInter, which in this case should be returning the interpretor for my current thread, which is fine. But your suggestion to NsTclVSetCmd() directly definitely sounds like a better idea. > You need to grab a lock for the particular interp and its thread. > That implies to me that you need to be able to specify the interp. > > Or, maybe you're right and my understanding of the nsv implementation > is wrong. Entirely possible. I haven't studied the tclvar.c much, but why would nsv locks have anything to do with threads at all? The nsv data structures are server-wide, after all, so I don't THINK there's anything per-thread or per-interp about them at all. It isn't obvious to me how those data structures are really set up though. There're the "Bucket" and "Array" struct typedefs, and then the "static Bucket *buckets" array, but I'm not entirely clear on how they all actually interact. > I do think that the "meat" of the actual nsv C code should be > refactored into a NsVSetCmd() or something similar, but if it isn't > safe to call directly, then perhaps that's a valid reason not to > refactor it out -- to prevent people from calling it wrong. I don't THINK there's any reason it wouldn't be safe to call the re-factored C functins directly. And I'd be willing to do the refactoring - not right now but sometime. So if somebody who really understands this can give some guidance on the locking and design questions Dossy raised, I'd appreciate it. -- Andrew Piskorski <[EMAIL PROTECTED]> http://www.piskorski.com
Re: [AOLSERVER] nsv API in C ?
On 2002.05.04, Andrew Piskorski <[EMAIL PROTECTED]> wrote: > On Sat, May 04, 2002 at 01:31:42AM -0400, Dossy wrote: > > Could you not call NsTclVSetCmd() yourself? Look in > > nsd/tclvar.c ... > > Hm. NsTclVSetCmd() does stuff to or with the Tcl interpretor, and I > don't HAVE any convenient local "interp" pointer in my C function to > pass is. Should I be passing the interp pointer into my C function, > so I can use it for things like NsTclVSetCmd()? Yes. That's what I would do. > But then, I should check the return value in the Tcl interp or > something to figure out what actually happened? I dunno. (Clearly > though, that wouldn't be any worse than the non-existant error > checking I have in my BB_NsvSet() using Ns_TclEval() right now.) If you're not passing the interp to Ns_TclEval to tell it in which interpreter to perform the TclEval ... then don't you wonder which interp it's using? > Basically, I don't understand why NsTclVSetCmd() is implemented the > way it is, rather than as a pair of two functions: > 1. NsVSetCmd() function for use by C which does not use any Tcl > interp at all. > 2. NsTclVSetCmd() which implements the nsv_set Tcl command and calls > NsVSetCmd() to do the actual work. You need to grab a lock for the particular interp and its thread. That implies to me that you need to be able to specify the interp. Or, maybe you're right and my understanding of the nsv implementation is wrong. Entirely possible. I do think that the "meat" of the actual nsv C code should be refactored into a NsVSetCmd() or something similar, but if it isn't safe to call directly, then perhaps that's a valid reason not to refactor it out -- to prevent people from calling it wrong. -- Dossy -- Dossy Shiobara mail: [EMAIL PROTECTED] Panoptic Computer Network web: http://www.panoptic.com/ "He realized the fastest way to change is to laugh at your own folly -- then you can let go and quickly move on." (p. 70)
Re: [AOLSERVER] nsv API in C ?
On Sat, May 04, 2002 at 01:31:42AM -0400, Dossy wrote: > Could you not call NsTclVSetCmd() yourself? Look in > nsd/tclvar.c ... Hm. NsTclVSetCmd() does stuff to or with the Tcl interpretor, and I don't HAVE any convenient local "interp" pointer in my C function to pass is. Should I be passing the interp pointer into my C function, so I can use it for things like NsTclVSetCmd()? But then, I should check the return value in the Tcl interp or something to figure out what actually happened? I dunno. (Clearly though, that wouldn't be any worse than the non-existant error checking I have in my BB_NsvSet() using Ns_TclEval() right now.) Basically, I don't understand why NsTclVSetCmd() is implemented the way it is, rather than as a pair of two functions: 1. NsVSetCmd() function for use by C which does not use any Tcl interp at all. 2. NsTclVSetCmd() which implements the nsv_set Tcl command and calls NsVSetCmd() to do the actual work. -- Andrew Piskorski <[EMAIL PROTECTED]> http://www.piskorski.com
Re: [AOLSERVER] nsv API in C ?
You should use the following: static int BB_NsvSet(const char *nsvString, const char *keyString, const char *valueString) { Tcl_Obj *o[4]; o[0]=Tcl_NewStringObj("nsv_set",7); o[1]=Tcl_NewStringObj(nsvString,-1); o[2]=Tcl_NewStringObj(keyString,-1); o[3]=Tcl_NewStringObj(valueString,-1); Tcl_IncrRefCount(o[0]); Tcl_IncrRefCount(o[1]); Tcl_IncrRefCount(o[2]); Tcl_IncrRefCount(o[3]); Tcl_EvalObjv(interp,4,&o[0],0); Tcl_DecrRefCount(o[0]); Tcl_DecrRefCount(o[1]); Tcl_DecrRefCount(o[2]); Tcl_DecrRefCount(o[3]); } This one uses Tcl objects (it won't work with 7.6 Tcl :), the main advantage is that it will set strings with quotes - like BB_NsvSet("a","b","\""); Your code will fail with this one. Don't know about speed performance though. Andrew Piskorski wrote: > Folks, has anyone implemented a C NSV API, or does anyone plan to? > > Clearly the right thing to do would be to move the functinality in > aolserver/nsd/tclvar.c into C API functions, and re-implement the nsv > Tcl commands to that C API. > > But since I needed to use some nsv commands from C, and I was in a > hurry, I just kludged up my own C NSV functions using Ns_TclEval, like > the example below. > > So has anybody done this in a less kludgy fashion? Also, any guesses > as to what sort of performance hit I'm taking by using Ns_TclEval? > > > static int > BB_NsvSet(const char *nsvString, > const char *keyString, const char *valueString) > { >static const char func_name[] = "BB_NsvSet"; >Ns_DString dsScript; >Ns_DString dsResult; >int rc; > >Ns_DStringInit(&dsScript); >Ns_DStringInit(&dsResult); > >/* > * The key and value may each have embedded whitespace, as we are > * surronding them with double quotes. But we asumme that the nsv > * array name will always be one word. > */ > >Ns_DStringVarAppend(&dsScript, "nsv_set ", nsvString, " ", >"\"", keyString, "\"", " ", >"\"", valueString, "\"", NULL); > >rc = Ns_TclEval(&dsResult, NULL, dsScript.string); > >Ns_DStringFree(&dsScript); >Ns_DStringFree(&dsResult); > >return rc; > } > > -- > Andrew Piskorski <[EMAIL PROTECTED]> > http://www.piskorski.com > > > -- WK "UTF-8 has a certain purity in that it equally annoys every nation, and is nobody's default encoding." -- Andy Robinson
Re: [AOLSERVER] nsv API in C ?
Could you not call NsTclVSetCmd() yourself? Look in nsd/tclvar.c ... -- Dossy On 2002.05.03, Andrew Piskorski <[EMAIL PROTECTED]> wrote: > Folks, has anyone implemented a C NSV API, or does anyone plan to? > > Clearly the right thing to do would be to move the functinality in > aolserver/nsd/tclvar.c into C API functions, and re-implement the nsv > Tcl commands to that C API. > > But since I needed to use some nsv commands from C, and I was in a > hurry, I just kludged up my own C NSV functions using Ns_TclEval, like > the example below. > > So has anybody done this in a less kludgy fashion? Also, any guesses > as to what sort of performance hit I'm taking by using Ns_TclEval? > > > static int > BB_NsvSet(const char *nsvString, > const char *keyString, const char *valueString) > { >static const char func_name[] = "BB_NsvSet"; >Ns_DString dsScript; >Ns_DString dsResult; >int rc; > >Ns_DStringInit(&dsScript); >Ns_DStringInit(&dsResult); > >/* > * The key and value may each have embedded whitespace, as we are > * surronding them with double quotes. But we asumme that the nsv > * array name will always be one word. > */ > >Ns_DStringVarAppend(&dsScript, "nsv_set ", nsvString, " ", >"\"", keyString, "\"", " ", >"\"", valueString, "\"", NULL); > >rc = Ns_TclEval(&dsResult, NULL, dsScript.string); > >Ns_DStringFree(&dsScript); >Ns_DStringFree(&dsResult); > >return rc; > } > > -- > Andrew Piskorski <[EMAIL PROTECTED]> > http://www.piskorski.com -- Dossy Shiobara mail: [EMAIL PROTECTED] Panoptic Computer Network web: http://www.panoptic.com/ "He realized the fastest way to change is to laugh at your own folly -- then you can let go and quickly move on." (p. 70)