[Openmcl-devel] Cockpit Error using SAVE-APPLICATION?

j-anthony at comcast.net j-anthony at comcast.net
Thu Nov 6 12:59:00 PST 2008




>> $ svn co
http://svn.clozure.com/publicsvn/openmcl/release/1.2/linuxx8664/ccl
>> A    ccl/LX86CL64
>> A    ccl/lx86cl64
>> svn: In directory 'ccl'
>> svn: Can't move source to dest
>> svn: Can't move 'ccl/.svn/tmp/prop-base/lx86cl64.svn-base' to
>> 'ccl/.svn/prop-base/lx86cl64.svn-base': No such file or directory

>The two most likely culprits that I can think of are:
...
> 2) you're on a case-insensitive filesystem (maybe because of running under

R. Matthew Emerson gave me this suggestion before I saw your reply here.  I
was surprised that the Mac has such a file system (being BSD based, I
thought it was just typical case sensitive uni*)  Anyway, I moved to a
Linux box and it just worked.  But...

The version svn gave me (11307) appears to be the exact same one as I had -
the image and kernel files are identical (and behave as the previous one in
this area - i.e., giving the original error caused by not having
initialized the interactive streams).  Did the change only get into the
source and I have to do a complete rebuild?


>> of this, I noticed that the default application class
>> LISP-DEVELOPMENT-SYSTEM didn't have such a method on it.

Applicable :before methods get called before the primary method, so
this happens when a LISP-DEVELOPMENT-SYSTEM starts up.

Oh, right - lisp-development-system is subclassed off application.


>It happens fairly late in the initialization process in 1.2  (because
>"initializiing interactive streams" involved setting up their character
>encoding, which could only be done after parsing command-line arguments
>happened, which ddepended on other things ...)  One consequence of this
>is that if errors happen very early in the initialization process,
something
>will try to write an error message to a stream that hasn't been initialized
>yet, causing an error, causing .. a trip to the kernel debugger with
>little indication of what the real problem was.

Ahhh, ok, I see how this fits together.


>"initializing  interactive streams" will be separated from (and happen
>earlier than) "setting the character encoding on *TERMINAL-IO*" in the
>next release.

OK, that would likely make the context/environment issues simpler.



>> Was this the
>> issue?  I notice that 'application is not external in CCL, so subclassing
>> an application class off this and using it probably isn't a "right" thing
>> to do?

>Basically, the :toplevel-function argument to SAVE-APPLICATION gets
>run instead of the TOPLEVEL-FUNCTION method of *APPLICATION*; it wasn't
>doing the stream initialization and wasn't running the function in
>a particularly reasonable environment (^C wasn't detected, FORCE-OUTPUT
>wasn't called on *TERMINAL-IO* automatically, etc.)

This makes sense (except I couldn't find in the prior version where the
toplevel passed in was called (i basically looked for a funcall in the
various l1-readloop* files.


>The changes that I checked in yesterday should make it more reasonable,
>but ultimately using an "application" object and methods on it is a
>better way of specifying more aspects of a saved application's behavior.
>The support for that is incomplete and tends to be a moving target,
>and it may still make sense to support the :TOPLEVEL-FUNCTION argument
>as a way of generating simple applications.

So, basically a reasonable alternative approach (even given the current
state of it's development) would be to subclass off APPLICATION (or perhaps
LISP-DEVELOPMENT-SYSTEM) and define a toplevel-function method on this and
then not pass in a :toplevel-function.  This would then cause the :before
methods to run and such and invoke the specific toplevel-function method
which would "do whatever".  Make sense?


>Calling QUIT should generally shut things down, yes.  The only cases
>where it might not involve things like:
>
>
>(tagbody
>   AGAIN
>   (unwind-protect
>       (do-something)
>    (go AGAIN)))

I see where that would be an issue, but fortunately nothing like this will
be in the toplevel.  Basically the toplevel would be more or less empty and
sleeping "forever".  Separate server threads would be catching and handling
incoming requests.  One of which, based on your input here, could be a
quit-app which would just (quit) and the whole thing would exit.


>The change that I made yesterday basically does the following, where
>USER-TOPLEVEL-FUNCTION is the :TOPLEVEL-FUNCTION argument to
SAVE-APPLICATION:

I will look for this - as I say the 1.2 (11307) didn't change at the binary
level at least.


>That's more reasonable than it was (and your example seems to work),
>but there are still some issues:
>
>- if QUIT isn't called after the user function returns, the thread
>will die but the initial thread will still sit there waiting for
>something interesting to happen.

Right - but it looks like your fix does call QUIT and so will exit the
initial thread (and thus the image) as well.


>- a ^C will cause the initial tread to interrupt itself, which
>usually isn't very interesting.

Ah - right.  Not the worst thing in the world though.


>- the thread running the user function doesn't "own" the input
>side of *TERMINAL-IO*, so things like Y-OR-N-P (or entrering
>a break loop) will "request ownership" of that stream (which
>is owned by the initial thread, which isn't doing anything
>too interesting with it.

I see - that could be an issue if the toplevel ever were to become
something more interesting.  Would this affect a swank like connection? 
Doesn't seem like it - in which case, you could use that to get that sort
of extra capability.



>What I think people often do (and one reason why this stuff isn't
>exercised too well) is something like:
>
>- load your code and save an image without specifying any non-default
>startup options
>
>- start the image with an --eval option
>
>shell> ccl64 -I my-image --eval \(start-my-server\)
>
>--eval gets processed after all of the initialization takes place
>but before the REPL is entered (and if START-MY-SERVER never returns,
>the REPL is never entered.)

I can see how this would work, but it doesn't seem as clean (and bullet
proof) as going about it using a custom toplevel (the technique of
subclassing and defining a toplevel-function method may be the cleanest
approach).


Thanks again,

/Jon


--------------------------------------------------------------------
mail2web.com - Microsoft® Exchange solutions from a leading provider -
http://link.mail2web.com/Business/Exchange





More information about the Openmcl-devel mailing list