/* This file provides the stubs needed for the AOL_SERVER, Please note, that you have to have to apply a small patch to the AOL server as well (available from www.xotcl.org) in order to get it working. Author: Zoran Vasiljevic Archiware Inc. Various updates from Gustaf Neumann */ #ifdef AOL_SERVER #include "xotcl.h" #include int Ns_ModuleVersion = 1; #if NS_MAJOR_VERSION>=4 # define AOL4 #endif /* *---------------------------------------------------------------------------- * * NsXotcl_Init -- * * Loads the package for the first time, i.e. in the startup thread. * * Results: * Standard Tcl result * * Side effects: * Package initialized. Tcl commands created. * *---------------------------------------------------------------------------- */ static int NsXotcl_Init (Tcl_Interp *interp, void *context) { static int firsttime = 1; int ret; ret = Xotcl_Init(interp); if (firsttime) { if (ret != TCL_OK) { Ns_Log(Warning, "can't load module %s: %s", (char *)context, Tcl_GetStringResult(interp)); } else { Ns_Log(Notice, "%s module version %s%s", (char*)context, XOTCLVERSION,XOTCLPATCHLEVEL); /* * Import the XOTcl namespace only for the shell after * predefined is through */ Tcl_Import(interp, Tcl_GetGlobalNamespace(interp), "xotcl::*", 0); } firsttime = 0; } return ret; } /* *---------------------------------------------------------------------------- * * NsXotcl_Init1 -- * * Loads the package in each thread-interpreter. * This is needed since XOTcl Class/Object commands are not copied * from the startup thread to the connection (or any other) thread. * during AOLserver initialization and/or thread creation times. * * Why ? * * Simply because these two commands declare a delete callback which is * unsafe to call in any other thread but in the one which created them. * * To understand this, you may need to get yourself acquainted with the * mechanics of the AOLserver, more precisely, with the way Tcl interps * are initialized (dive into nsd/tclinit.c in AOLserver distro). * * So, we made sure (by patching the AOLserver code) that no commands with * delete callbacks declared, are ever copied from the startup thread. * Additionaly, we also made sure that AOLserver properly invokes any * AtCreate callbacks. So, instead of activating those callbacks *after* * running the Tcl-initialization script (which is the standard behaviour) * we activate them *before*. So we may get a chance to configure the * interpreter correctly for any commands within the init script. * * Proper XOTcl usage would be to declare all resources (classes, objects) * at server initialization time and let AOLserver machinery to copy them * (or re-create them, better yet) in each new thread. * Resources created within a thread are automatically garbage-collected * on thread-exit time, so don't create any XOTcl resources there. * Create them in the startup thread and they will automatically be copied * for you. * Look in /modules/tcl/xotcl for a simple example. * * Results: * Standard Tcl result. * * Side effects: * Tcl commands created. * *---------------------------------------------------------------------------- */ static int NsXotcl_Init1 (Tcl_Interp *interp, void *notUsed) { int result; #ifndef AOL4 result = Xotcl_Init(interp); #else result = TCL_OK; #endif /* * Import the XOTcl namespace only for the shell after * predefined is through */ Tcl_Import(interp, Tcl_GetGlobalNamespace(interp), "xotcl::*", 1); return result; } /* *---------------------------------------------------------------------------- * * Ns_ModuleInit -- * * Called by the AOLserver when loading shared object file. * * Results: * Standard AOLserver result * * Side effects: * Many. Depends on the package. * *---------------------------------------------------------------------------- */ int Ns_ModuleInit(char *hServer, char *hModule) { int ret; /*Ns_Log(Notice, "+++ ModuleInit","INIT");*/ ret = Ns_TclInitInterps(hServer, NsXotcl_Init, (void*)hModule); if (ret == TCL_OK) { /* * See discussion for NsXotcl_Init1 procedure. * Note that you need to patch AOLserver for this to work! * The patch basically forbids copying of C-level commands with * declared delete callbacks. It also runs all AtCreate callbacks * BEFORE AOLserver runs the Tcl script for initializing new interps. * These callbacks are then responsible for setting up the stage * for correct (XOTcl) extension startup (including copying any * XOTcl resources (classes, objects) created in the startup thread. */ Ns_TclRegisterAtCreate((Ns_TclInterpInitProc *)NsXotcl_Init1, NULL); } return ret == TCL_OK ? NS_OK : NS_ERROR; } #endif