>ns_after 1 {ns_thread begindetached [list atp_test foo bar]}
>
>This should create the thread 1 second after startup with the full
>environment. The reason is the scheduler has a call to Ns_WaitForStartup()
>at the top of the SchedThread main in nsd/sched.c so it won't process the
I tried this, still some problems, please see below.
>ns_after request until the server is fully initialized. Note that if your
>Tcl thread is long running, you'll need to do the right thing to manage state
>manually as it won't benefit from the regular cleanup/update effects of
>Ns_TclAllocateInterp/Ns_TclDeAllocateInterp as with ordinary transactions. A
>call to "ns_cleanup" or perhaps "ns_ictl update" in the body of your while
>loop may work. Unfortunately this stuff is not well documented or understood
>as most folks don't need to bother with it - check the code in nsd/tclinit.c
>and nsd/init.tcl for details.
?? Sorry, I don't follow. Why would any special manual cleanup in a
long-running detached thread be necessary? And this is completely
different from 3.x, right? I looked at the ns_cleanup, ns_ictl
update, etc. code but that wasn't enough for me to understand what's
going on...
Well, consider this a feature of AOLserver 4.0 :). These are new hooks to enable regular cleanup but you don't have to use them. Basically, the cleanup stuff clears out temporary ns_set's, frees global vars, and can detect changes in the Tcl procs from the use of ns_eval. However, if your code didn't bother with this stuff in 3.x it's likely you can ignore it in 4.0.
Using ns_after 1 thing helped, but seemed to only let things get far
enough to expose additional problems. Now, I seem to have these two
problems:
- The BB_Nsv* C functions I've created in my nsvapi.c still aren't
working right in some cases, Tcl_GetCommandInfo is still claiming that
"nsv_set", etc. don't exist. This is despite the fact that the thread
calling these is now being spawned AFTER full server initialization.
Are you using Ns_TclAllocateInterp to get your interp with a NULL server arg within your Ns_ModuleInit? This would provide you a non-virtual server interp similar to the config interp with no nsv commands. This may have worked in 3.x because you would be messing with a "master interp" which would be dup'ed to other interps later as needed.
If this is your problem, you need to use the Ns_TclInitInterp's API:
int
Ns_ModuleInit(char *module, char *server)
{
Ns_TclInitInterps(server, MyInit, mydata);
...
}
int
MyInit(Tcl_Interp *interp, void *arg)
{
MyData *mydata = arg;
...do as you wish with interp - it should be fully initialized as a virtual server interp ...
return TCL_OK;
}
Note that the above has been the recommended way for initializing interps since way back in AOLserver 2.0 which the function would iterate over a pool of interps. In 3.x it just immediately invoked your callback on the "master interp". In 4.0 it registers your callback to be run when new interps are created for the given server - no matter how (detached thread, connection thread, etc.). This is a key difference in how 3.x and 4.0 Tcl in managed. The rationale was to enable more standard Tcl initialization eventually.
- Ns_TclInterpServer (called with a NULL Tcl interp), is segfaulting
when calling Tcl_GetAssocData.
Ns_TclInterpServer shouldn't be called with NULL - it needs to dig out the server from the interp. I believe 3.x just returned a global variable. However, I would say it shouldn't cause a crash and NsGetInterp() should handle the NULL interp. Anyway, as with the other virtual server related API's in 4.0 such as Ns_TclAllocateInterp above you now need to pass a valid server.
As for the rationale of adding virtual servers in the first place in 2.x, removing them in 3.x, and returning them in 4.0 it's all water under the bridge now. Basically, they were added in 2.x to support AOL's now defunct Primehost web hosting business, I removed them in 3.x in an effort to streamline the code (the 2.x virtual server code was complex and inefficient), and I added them back into 4.0 because I figured out ways to make it work without being inefficient and people had complained that they were removed. I figured it may cause some people problems if they did some "virtual server cheating" in 3.x. In fact, some of the 3.x modules bundled with aolserver (e.g., nscp) cheated.
It turns out I played around with some code that would ignore the virtual server mess in 4.0 if only one server was configured but removed it because it started looking messy and hard to maintain. I'm guessing you can fix up your code pretty quick to deal with the virtual servers and it should work with 3.x as well.
-Jim
