Barry Margolin <barmar@genuity.net> wrote:
+---------------
| However, since we're talking about using an interpreter as the server,
| it would not be difficult to design the interpreter so that each script
| invocation operated in its own sandbox. When the invocation completes,
| the sandbox would be destroyed, freeing all the data that was allocated
| within it.
+---------------
Look at MzScheme's threads/namespaces/parameters/custodians:
<URL:http://www.cs.rice.edu/CS/PLT/packages/doc/mzscheme/node91.htm>
In particular:
A custodian manages a collection of threads, file-stream ports,
process ports, TCP ports, and TCP listeners, [and has] the authority
to shut down all of its managed values.
...
(custodian-shutdown-all custodian) kills all running threads, closes
all open ports, and closes all active TCP listeners that are managed
by the custodian.
So if you create a new custodian for each request, make it the "current
custodian", then create a thread to satisfy the request, if the parent
server (also a thread) shuts down that custodian (e.g., for an idle timeout,
or because the thread exited) any files that were opened (including sockets)
will be closed.
And of course, when a thread shuts down, any data held locally within it
gets GC'd (eventually).
+---------------
| Certainly something like this is also needed to keep the scripts from
| interfering with each other if they make use of global variables. "Global"
| would mean global within that invocation's sandbox, not global to the
| entire interpreter.
+---------------
Again, MzScheme provides multiple global variable namespaces which
should handle this perfectly:
The current namespace is used by eval, load, compile, and
expand-defmacro. Once an expression is evaled or compiled,
the global variable references in the compiled expression
are permanently attached to a particular namespace, so the
current namespace at the time that the code is executed is
not used as the namespace for referencing global variables
in the expression.
Example:
(define x 'orig) ; define in the original namespace
; The following let expression is compiled in the original
; namespace, so direct references to x see 'orig.
(let ([n (make-namespace)]) ; make new namespace
(parameterize ([current-namespace n])
(eval '(define x 'new)) ; evals in the new namespace
(display x) ; displays 'orig
(display (eval 'x)))) ; displays 'new
Note that DrScheme depends on namespaces to keep user programs being
debugged from interfering with DrScheme's own globals.
-Rob
-----
Rob Warnock, 31-2-510 rpw3@sgi.com
SGI Network Engineering <URL:http://reality.sgi.com/rpw3/>
1600 Amphitheatre Pkwy. Phone: 650-933-1673
Mountain View, CA 94043 PP-ASEL-IA