1/* $Id: aolstub.c,v 1.1 2004/05/23 22:50:39 neumann Exp $
2
3   This file provides the stubs needed for the AOL_SERVER,
4   Please note, that you have to have to apply a small patch
5   to the AOL server as well (available from www.xotcl.org)
6   in order to get it working.
7
8   Authore:
9      Zoran Vasiljevic
10      Archiware Inc.
11
12*/
13#ifdef AOL_SERVER
14
15
16#include "xotcl.h"
17#include <ns.h>
18
19int Ns_ModuleVersion = 1;
20
21#if NS_MAJOR_VERSION>=4
22# define AOL4
23#endif
24
25/*
26 *----------------------------------------------------------------------------
27 *
28 * NsXotcl_Init --
29 *
30 *    Loads the package for the first time, i.e. in the startup thread.
31 *
32 * Results:
33 *    Standard Tcl result
34 *
35 * Side effects:
36 *    Package initialized. Tcl commands created.
37 *
38 *----------------------------------------------------------------------------
39 */
40
41
42static int
43NsXotcl_Init (Tcl_Interp *interp, void *context)
44{
45 static int firsttime = 1;
46 int ret;
47
48 ret = Xotcl_Init(interp);
49
50 if (firsttime) {
51   if (ret != TCL_OK) {
52     Ns_Log(Warning, "can't load module %s: %s", (char *)context,
53	    Tcl_GetStringResult(interp));
54   } else {
55     Ns_Log(Notice, "%s module version %s%s", (char*)context,
56	    XOTCLVERSION,XOTCLPATCHLEVEL);
57     /*
58      * Import the XOTcl namespace only for the shell after
59      * predefined is through
60      */
61     Tcl_Import(interp, Tcl_GetGlobalNamespace(interp),
62		"xotcl::*", 0);
63   }
64   firsttime = 0;
65 }
66
67 return ret;
68}
69
70/*
71 *----------------------------------------------------------------------------
72 *
73 * NsXotcl_Init1 --
74 *
75 *    Loads the package in each thread-interpreter.
76 *    This is needed since XOTcl Class/Object commands are not copied
77 *    from the startup thread to the connection (or any other) thread.
78 *    during AOLserver initialization and/or thread creation times.
79 *
80 *    Why ?
81 *
82 *    Simply because these two commands declare a delete callback which is
83 *    unsafe to call in any other thread but in the one which created them.
84 *
85 *    To understand this, you may need to get yourself acquainted with the
86 *    mechanics of the AOLserver, more precisely, with the way Tcl interps
87 *    are initialized (dive into nsd/tclinit.c in AOLserver distro).
88 *
89 *    So, we made sure (by patching the AOLserver code) that no commands with
90 *    delete callbacks declared, are ever copied from the startup thread.
91 *    Additionaly, we also made sure that AOLserver properly invokes any
92 *    AtCreate callbacks. So, instead of activating those callbacks *after*
93 *    running the Tcl-initialization script (which is the standard behaviour)
94 *    we activate them *before*. So we may get a chance to configure the
95 *    interpreter correctly for any commands within the init script.
96 *
97 *    Proper XOTcl usage would be to declare all resources (classes, objects)
98 *    at server initialization time and let AOLserver machinery to copy them
99 *    (or re-create them, better yet) in each new thread.
100 *    Resources created within a thread are automatically garbage-collected
101 *    on thread-exit time, so don't create any XOTcl resources there.
102 *    Create them in the startup thread and they will automatically be copied
103 *    for you.
104 *    Look in <serverroot>/modules/tcl/xotcl for a simple example.
105 *
106 * Results:
107 *    Standard Tcl result.
108 *
109 * Side effects:
110 *    Tcl commands created.
111 *
112 *----------------------------------------------------------------------------
113 */
114
115static int
116NsXotcl_Init1 (Tcl_Interp *interp, void *notUsed)
117{
118  int result;
119
120#ifndef AOL4
121  result = Xotcl_Init(interp);
122#else
123  result = TCL_OK;
124#endif
125
126  /*
127   * Import the XOTcl namespace only for the shell after
128   * predefined is through
129   */
130  Tcl_Import(interp, Tcl_GetGlobalNamespace(interp), "xotcl::*", 1);
131
132  return result;
133}
134
135/*
136 *----------------------------------------------------------------------------
137 *
138 * Ns_ModuleInit --
139 *
140 *    Called by the AOLserver when loading shared object file.
141 *
142 * Results:
143 *    Standard AOLserver result
144 *
145 * Side effects:
146 *    Many. Depends on the package.
147 *
148 *----------------------------------------------------------------------------
149 */
150
151int
152Ns_ModuleInit(char *hServer, char *hModule)
153{
154  int ret;
155
156  /*Ns_Log(Notice, "+++ ModuleInit","INIT");*/
157  ret = Ns_TclInitInterps(hServer, NsXotcl_Init, (void*)hModule);
158
159  if (ret == TCL_OK) {
160    /*
161     * See discussion for NsXotcl_Init1 procedure.
162     * Note that you need to patch AOLserver for this to work!
163     * The patch basically forbids copying of C-level commands with
164     * declared delete callbacks. It also runs all AtCreate callbacks
165     * BEFORE AOLserver runs the Tcl script for initializing new interps.
166     * These callbacks are then responsible for setting up the stage
167     * for correct (XOTcl) extension startup (including copying any
168     * XOTcl resources (classes, objects) created in the startup thread.
169     */
170    Ns_TclRegisterAtCreate((Ns_TclInterpInitProc *)NsXotcl_Init1, NULL);
171  }
172
173  return ret == TCL_OK ? NS_OK : NS_ERROR;
174}
175#endif
176