[Openmcl-devel] Handling error in a callback
gb at clozure.com
Mon Mar 29 20:46:57 EST 2004
On Mon, 29 Mar 2004, Rick Taube wrote:
> > How are we suppose to do in this case? Do we need to wrap the callback
> > Lisp code with an error catcher block?
> Also, its would be helpful to be able to see error messagea when they
> happens, but Im not quite sure how to get the lisp code called by the
> foreign process to print in the lisp terminal when an error happens.
> Sometimes, when I get an error, OpenMCL notifies me that a process is
> attempting to write to the terminal, but the message itself is not
> visible. Ive tried several things with *terminal-io* inside the
> callback code but im afraid Im just stabbing in the dark, do i need to
> lock it somehow, or use someting like with-terminal-input but for
> output? Any advice would be appreciated!
> Rick Taube
> Associate Professor, Composition/Theory
> School of Music
> University of Illinois
> Urbana, IL 61821 USA
> net: taube at uiuc.edu
> fax: 217 244 8319
> vox: 217 244 2684
First of all: there was a bad bug in the way that special variables were
bound when a foreign thread (one not created by lisp) first called back
to lisp; the fix for this in CVS (and was mailed to this last a couple
of weeks ago.)
With that in effect, a simple case seems to work as expected, up to a
Welcome to OpenMCL Version (Beta: Darwin) 0.14.1-p1!
? (defun run-in-foreign-thread (callback string-arg)
(let ((s (ccl::make-cstring string-arg)))
(rlet ((pthread :pthread_t))
(if (eql 0 (#_pthread_create pthread (%null-ptr) callback s))
(pref pthread :pthread_t)))))
? (defcallback signal-an-error-in-lisp (:address arg :void)
(error "Error: ~a" (%get-cstring arg)))
? (run-in-foreign-thread signal-an-error-in-lisp "something bad happened")
#<A Mac Pointer #x803A00>
> Error in process foreign(2): Error: something bad happened
> While executing: SIGNAL-AN-ERROR-IN-LISP
;;; #<PROCESS foreign(2) [Foreign thread callback] #x547FD4E> requires access to Shared Terminal Input
;;; Shared Terminal Input is now owned by #<PROCESS foreign(2) [Foreign thread callback] #x547FD4E>
> Type :POP to abort.
Type :? for other options.
Past this point, a few things that should work don't seem to:
a) Backtrace (:b) seems to have difficulty parsing the foreign thread's
stack; I've seen it segfault and otherwise become confused, but don't
yet understand what the problem is.
b) Exiting from a break loop tries to invoke an ABORT restart; the
foreign thread hasn't established such a restart, so this leads to
the cryptic error:
Restart NIL is not active
and there's no good way to exit the (nested) break loop.
You should clearly be able to exit the break loop in this situation;
it's less clear to me where you should exit -to-. (One reasonable
choice might be to simply unwind out of as much lisp code as we can
and kill the thread.)
Unless they make other provisions, all threads (including foreign ones)
share the same *TERMINAL-IO* (and the other standard streams are SYNONYM-
STREAMs to *TERMINAL-IO*). A lot of fuss is made about which thread is
able to read from *TERMINAL-IO*; writing to it just involves waiting for
a lock, so it's not clear who'd be telling you that a process is waiting
for some sort of write access; I don't believe that any such message would
come from OpenMCL itself.
More information about the Openmcl-devel