From: Stephen D. <sd...@us...> - 2005-10-09 22:27:30
|
Update of /cvsroot/naviserver/naviserver/nsd In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26895/nsd Modified Files: init.tcl modload.c nsd.h nsmain.c server.c tclcallbacks.c tclcmds.c tclmisc.c Log Message: * nsd/nsd.h: * nsd/modload.c: * nsd/nsmain.c: * nsd/server.c: * nsd/init.tcl: Add new Tcl command ns_moduleload which loads a binary module into the server and calls it's initialising function. Remove NsLoadModules and instead call ns_moduleload from the init.tcl bootstrap. Policy about where modules are located and when they are loaded is now easily accessible to Tcl. * nsd/tclcallbacks.c: * nsd/tclmisc.c: * nsd/tclcmds.c: Add new command ns_atprestartup as a simple wrapper for the C equivalent. Add new command ns_runonce which ensures that the given script is run only once, either globally or per virtual server, during the lifetime of the server process. This simplifies initialisation. Index: tclmisc.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/tclmisc.c,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** tclmisc.c 30 Jul 2005 03:17:50 -0000 1.12 --- tclmisc.c 9 Oct 2005 22:27:24 -0000 1.13 *************** *** 79,82 **** --- 79,137 ---- *---------------------------------------------------------------------- * + * NsTclRunOnceObjCmd -- + * + * Implements ns_runonce. Run the given script only once. + * + * Results: + * Tcl result. + * + * Side effects: + * Depends on script. + * + *---------------------------------------------------------------------- + */ + + int + NsTclRunOnceObjCmd(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) + { + NsInterp *itPtr = arg; + CONST char *script; + int new, global = NS_FALSE; + static Tcl_HashTable runTable; + static int initialized; + + Ns_ObjvSpec opts[] = { + {"-global", Ns_ObjvBool, &global, (void *) NS_TRUE}, + {"--", Ns_ObjvBreak, NULL, NULL}, + {NULL, NULL, NULL, NULL} + }; + Ns_ObjvSpec args[] = { + {"script", Ns_ObjvString, &script, NULL}, + {NULL, NULL, NULL, NULL} + }; + if (Ns_ParseObjv(opts, args, interp, 1, objc, objv) != NS_OK) { + return TCL_ERROR; + } + + Ns_MasterLock(); + if (!initialized) { + Tcl_InitHashTable(&runTable, TCL_STRING_KEYS); + initialized = NS_TRUE; + } + (void) Tcl_CreateHashEntry(global ? &runTable : &itPtr->servPtr->tcl.runTable, + script, &new); + Ns_MasterUnlock(); + + if (new) { + return Tcl_Eval(interp, script); + } + + return TCL_OK; + } + + + /* + *---------------------------------------------------------------------- + * * Ns_TclLogErrorInfo -- * Index: tclcallbacks.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/tclcallbacks.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** tclcallbacks.c 10 Jun 2005 17:58:39 -0000 1.2 --- tclcallbacks.c 9 Oct 2005 22:27:24 -0000 1.3 *************** *** 268,271 **** --- 268,277 ---- int + NsTclAtPreStartupObjCmd(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) + { + return AtObjCmd(Ns_RegisterAtPreStartup, interp, objc, objv); + } + + int NsTclAtStartupObjCmd(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { Index: server.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/server.c,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** server.c 2 Oct 2005 22:39:06 -0000 1.12 --- server.c 9 Oct 2005 22:27:24 -0000 1.13 *************** *** 292,295 **** --- 292,296 ---- Tcl_IncrRefCount(servPtr->tcl.modules); Ns_RWLockInit(&servPtr->tcl.lock); + Tcl_InitHashTable(&servPtr->tcl.runTable, TCL_STRING_KEYS); servPtr->nsv.nbuckets = Ns_ConfigIntRange(path, "nsvbuckets", 8, 1, INT_MAX); servPtr->nsv.buckets = NsTclCreateBuckets(server, servPtr->nsv.nbuckets); *************** *** 488,493 **** CreatePool(servPtr, Ns_SetKey(set, i)); } - NsLoadModules(server); NsTclInitServer(server); initServPtr = NULL; } --- 489,494 ---- CreatePool(servPtr, Ns_SetKey(set, i)); } NsTclInitServer(server); + NsInitStaticModules(server); initServPtr = NULL; } Index: nsmain.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/nsmain.c,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** nsmain.c 8 Oct 2005 16:37:52 -0000 1.21 --- nsmain.c 9 Oct 2005 22:27:24 -0000 1.22 *************** *** 678,685 **** /* ! * Load non-server modules. */ ! NsLoadModules(NULL); /* --- 678,685 ---- /* ! * Initialize non-server static modules. */ ! NsInitStaticModules(NULL); /* Index: modload.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/modload.c,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** modload.c 9 Oct 2005 22:14:53 -0000 1.6 --- modload.c 9 Oct 2005 22:27:24 -0000 1.7 *************** *** 195,269 **** *---------------------------------------------------------------------- * ! * NsLoadModules -- * ! * Load all modules for given server. * * Results: ! * None. * * Side effects: ! * Will load and initialize modules. * *---------------------------------------------------------------------- */ ! void ! NsLoadModules(CONST char *server) { ! Ns_Set *modules; ! int i; ! char *file, *module, *init = NULL, *s, *e = NULL; ! Module *modPtr, *nextPtr; ! ! modules = Ns_ConfigGetSection(Ns_ConfigGetPath(server, NULL, ! "modules", NULL)); ! for (i = 0; modules != NULL && i < Ns_SetSize(modules); ++i) { ! module = Ns_SetKey(modules, i); ! file = Ns_SetValue(modules, i); ! ! /* ! * Check for specific module init after filename. ! */ ! ! s = strchr(file, '('); ! if (s == NULL) { ! init = "Ns_ModuleInit"; ! } else { ! *s = '\0'; ! init = s + 1; ! e = strchr(init, ')'); ! if (e != NULL) { ! *e = '\0'; ! } ! } ! ! /* ! * Load the module if it's not the reserved "tcl" name. ! */ ! ! if (!STRIEQ(file, "tcl") ! && Ns_ModuleLoad(server, module, file, init) != NS_OK) { ! Ns_Fatal("modload: %s: failed to load module", file); ! } ! /* ! * Add this module to the server Tcl init list. ! */ ! Ns_TclInitModule(server, module); ! if (s != NULL) { ! *s = '('; ! if (e != NULL) { ! *e = ')'; ! } ! } ! } ! /* ! * Initialize the static modules (if any). Note that a static ! * module could add a new static module and so the loop is ! * repeated until they're all gone. ! */ while (firstPtr != NULL) { --- 195,272 ---- *---------------------------------------------------------------------- * ! * NsTclModuleLoadObjCmd -- * ! * Implements ns_moduleload. Load and initilize a binary module. * * Results: ! * Tcl result. * * Side effects: ! * Will exit the server with a fatal error if module fails to load ! * initialize correctly. * *---------------------------------------------------------------------- */ ! int ! NsTclModuleLoadObjCmd(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { ! NsInterp *itPtr = (NsInterp *) arg; ! CONST char *server, *module, *file, *init = "Ns_ModuleInit"; ! int global = NS_FALSE; ! Ns_ObjvSpec opts[] = { ! {"-global", Ns_ObjvBool, &global, (void *) NS_TRUE}, ! {"-init", Ns_ObjvString, &init, NULL}, ! {"--", Ns_ObjvBreak, NULL, NULL}, ! {NULL, NULL, NULL, NULL} ! }; ! Ns_ObjvSpec args[] = { ! {"module", Ns_ObjvString, &module, NULL}, ! {"file", Ns_ObjvString, &file, NULL}, ! {NULL, NULL, NULL, NULL} ! }; ! if (Ns_ParseObjv(opts, args, interp, 1, objc, objv) != NS_OK) { ! return TCL_ERROR; ! } ! if (Ns_InfoStarted()) { ! Tcl_SetResult(interp, "server already started", TCL_STATIC); ! return TCL_ERROR; ! } ! if (global) { ! server = NULL; ! } else { ! server = itPtr->servPtr->server; ! } ! if (Ns_ModuleLoad(server, module, file, init) != NS_OK) { ! Ns_Fatal("modload: failed to load module '%s'", file); ! } ! return TCL_OK; ! } ! ! /* ! *---------------------------------------------------------------------- ! * ! * NsInitStaticModules -- ! * ! * Initialize static modules for given server, or global static ! * modules if no server given. ! * ! * Results: ! * None. ! * ! * Side effects: ! * Static modules may register new static modules, so we loop ! * until they're all gone. ! * ! *---------------------------------------------------------------------- ! */ ! void ! NsInitStaticModules(CONST char *server) ! { ! Module *modPtr, *nextPtr; while (firstPtr != NULL) { Index: nsd.h =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/nsd.h,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -d -r1.34 -r1.35 *** nsd.h 2 Oct 2005 22:39:06 -0000 1.34 --- nsd.h 9 Oct 2005 22:27:24 -0000 1.35 *************** *** 637,640 **** --- 637,641 ---- int epoch; Tcl_Obj *modules; + Tcl_HashTable runTable; CONST char **errorLogHeaders; } tcl; *************** *** 937,940 **** --- 938,942 ---- extern void NsTclInitServer(CONST char *server) NS_GNUC_NONNULL(1); + extern void NsInitStaticModules(CONST char *server); extern NsInterp *NsGetInterpData(Tcl_Interp *interp) NS_GNUC_NONNULL(1); *************** *** 942,946 **** NS_GNUC_NONNULL(1); - extern void NsLoadModules(CONST char *server); extern struct Bucket *NsTclCreateBuckets(char *server, int nbuckets); --- 944,947 ---- Index: tclcmds.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/tclcmds.c,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** tclcmds.c 8 Oct 2005 12:06:07 -0000 1.20 --- tclcmds.c 9 Oct 2005 22:27:24 -0000 1.21 *************** *** 66,69 **** --- 66,70 ---- NsTclAtCloseObjCmd, NsTclAtExitObjCmd, + NsTclAtPreStartupObjCmd, NsTclAtShutdownObjCmd, NsTclAtSignalObjCmd, *************** *** 102,105 **** --- 103,107 ---- NsTclLogObjCmd, NsTclLogRollObjCmd, + NsTclModuleLoadObjCmd, NsTclModulePathObjCmd, NsTclMutexObjCmd, *************** *** 139,142 **** --- 141,145 ---- NsTclReturnUnauthorizedObjCmd, NsTclRollFileObjCmd, + NsTclRunOnceObjCmd, NsTclSHA1ObjCmd, NsTclSchedDailyObjCmd, *************** *** 233,236 **** --- 236,240 ---- {"ns_after", NULL, NsTclAfterObjCmd}, {"ns_atexit", NULL, NsTclAtExitObjCmd}, + {"ns_atprestartup", NULL, NsTclAtPreStartupObjCmd}, {"ns_atshutdown", NULL, NsTclAtShutdownObjCmd}, {"ns_atsignal", NULL, NsTclAtSignalObjCmd}, *************** *** 374,377 **** --- 378,382 ---- {"ns_ictl", NULL, NsTclICtlObjCmd}, {"ns_library", NsTclLibraryCmd, NULL}, + {"ns_moduleload", NULL, NsTclModuleLoadObjCmd}, {"ns_puts", NULL, NsTclAdpPutsObjCmd}, {"ns_register_adp", NULL, NsTclRegisterAdpObjCmd}, *************** *** 393,396 **** --- 398,402 ---- {"ns_returnredirect", NULL, NsTclReturnRedirectObjCmd}, {"ns_returnunauthorized", NULL, NsTclReturnUnauthorizedObjCmd}, + {"ns_runonce", NULL, NsTclRunOnceObjCmd}, {"ns_server", NULL, NsTclServerObjCmd}, {"ns_setcookie", NULL, NsTclSetCookieObjCmd}, Index: init.tcl =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/init.tcl,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** init.tcl 30 Jul 2005 03:35:10 -0000 1.3 --- init.tcl 9 Oct 2005 22:27:24 -0000 1.4 *************** *** 612,615 **** --- 612,644 ---- } + # + # Load global binary modules. + # + + ns_runonce -global { + ns_atprestartup { + set modules [ns_configsection ns/modules] + if {![string equal $modules ""]} { + foreach {module file} [ns_set array $modules] { + ns_moduleload -global $module $file + } + } + } + } + + # + # Load binary modules for this server. + # + + set modules [ns_configsection ns/server/[ns_info server]/modules] + if {![string equal $modules ""]} { + foreach {module file} [ns_set array $modules] { + if {![string equal [string tolower $module] tcl]} { + ns_moduleload $module $file + } + ns_ictl addmodule $module + } + } + # *************** *** 646,651 **** # set srv [ns_info server] ! if {![nsv_exists _ns_eval_jobq $srv]} { ! nsv_set _ns_eval_jobq $srv [ns_job create "ns_eval_q:$srv" 1] } --- 675,680 ---- # set srv [ns_info server] ! ns_runonce { ! ns_job create "ns_eval_q:$srv" 1 } |