[Ecls-list] ECL-generated executables and restarts

Matthew Mondor mm_lists at pulsar-zone.net
Sat Jan 22 12:09:37 UTC 2011


On Sat, 22 Jan 2011 00:15:35 +0100
Juan Jose Garcia-Ripoll <juanjose.garciaripoll at googlemail.com> wrote:

> Well, then I think I might know the problem. If this is a multithreaded ECL,
> when SIGINT is received, it is handled by a separate thread. However, this
> thread is spawned by a thread which is created before your code is executed.
> In other words, the handler thread never gets to see your restarts. At most
> the *debugger-hook* might be used to "push" restarts, but not that they do
> not make much sense, since they are executed on a standalone thread, where
> the notion of "continue" does not make much sense.

It is indeed a multithreaded ECL build.  However that particular
application doesn't need multiple threads (but indeed two threads can
be shown running).  I've been wondering if it would be easy to create
non-threaded final executables from a threaded ECL build, but I think
it'd be a lot of trouble, as there are C macros expanding differently,
etc.  I also could have two ECL builds to do that however.  But I think
I'll keep using the threaded version which usually works fine, and
allows to discover potential bugs.

As for the SIGINT issue, I think that it would be solved if I left the
main thread for SWANK and used another thread for the main loop, which
is something I have done previously for a test HTTP server, but I admit
I still have to run that under -current ECL, it's been a while.

> In an "ordinary" ECL the situation is a bit different, as the debugger is
> better "installed" and what it does is coordinate with the already running
> toplevel. I will look into your examples, which are clear and simple enough,
> to see what is going on there -- the third example is particularly ugly.

I also received an interesting suggestion from another list reader:


Polos Ruetz <polos.ruetz at gmail.com> wrote:

In my projects, in order to have the top level always executing, I
start them like so:

(with-input-from-string (s "(my-ini-code)") ; custom ini code
 (let ((*standard-input* s))
   (si:top-level)))

(Just a suggestion, maybe there's a better way.)


Thanks for the suggestion, here is an adapted test-case:


(defvar *input* *standard-input*)

(defun custom ()
  (let ((*standard-input* *input*))
    (format t "~%Let's read~%")
    (read-line)
    (format t "~%Done~%"))
  (ext:quit))

(restart-case
    (with-input-from-string (s "(custom)") ; custom ini code
      (let ((*standard-input* s))
	(si:top-level)))
  (my-restart ()
    (format t "~%ABORTING!~%")
    (ext:quit)))
(ext:quit)


For this stdin I/O test case, obviously I had to remember
*standard-input* and rebind it before read-line, otherwise an immediate
EOF error would occur (under which case as with other type of
conditions MY-RESTART was available).  If I type CTRL-C to send a
SIGINT in this case, I get the exact same behavior than before,
however.  And I now understand why after your explanation about how
SIGINT is dealt with in threaded mode.

Thanks,
-- 
Matt




More information about the ecl-devel mailing list