Hi,
I'm trying to write a wrapper to Apple's CoreMIDI framework with CFFI. CoreMIDI midi input is callback based, the framework creates a thread for you and then calls your given callback on that thread. I wrapped the necessary functions but whenever my program receives midi it crashes to the ldb debugger with a bus error (signal 10). After digging around for a while I came across the following thread:
http://common-lisp.net/pipermail/cffi-devel/2009-May/003121.html
According to the thread I can't callback into lisp on a non-lisp-created thread. Is there anyway to 'bless' a thread so i can callback to lips? Or is the only way to buffer the input in the C thread and then access it from a separate lisp thread? (I'm a lisp beginner using SBCL by the way.)
Maybe it would be nice to put a note in the callback part of the CFFI manual warning about this gotcha?
Thanks for any help or pointers, Bodhi
On Tue, 16 Jun 2009 17:23:50 -0700, Bodhi bodhi@5263.org wrote:
According to the thread I can't callback into lisp on a non-lisp-created thread. Is there anyway to 'bless' a thread so i can callback to lips?
Corman Common Lisp FFI allows a thread to be blessed. I don't know if any other Lisp supports this though.
Or is the only way to buffer the input in the C thread and then access it from a separate lisp thread? (I'm a lisp beginner using SBCL by the way.)
I had to write a C wrapper library to handle the callback. The wrapper library then calls back into the Lisp process.
Maybe it would be nice to put a note in the callback part of the CFFI manual warning about this gotcha?
It bit me so a note would be a good idea, I think.
- Luke
On Wed, Jun 17, 2009 at 2:21 AM, Luke J Crookluke@balooga.com wrote:
Corman Common Lisp FFI allows a thread to be blessed. I don't know if any other Lisp supports this though.
Clozure CL seems to this automagically. Gary Byers described the issue in detail in this message http://www.clozure.com/pipermail/openmcl-devel/2003-May/004781.html. Although he says "that code isn't written yet", apparently it has been written since then.
Here's a quick test to check whether your Lisp supports callbacks from random threads.
(in-package :cffi)
(load-foreign-library "libpthread.so.0")
(defcallback foo :pointer ((arg :pointer)) (declare (ignore arg)) (print 'called-into-lisp-from-foreign-thread) (null-pointer))
(defctype pthread-t :unsigned-long)
(with-foreign-object (th 'pthread-t) (foreign-funcall "pthread_create" :pointer th :pointer (null-pointer) :pointer (callback foo) :pointer (null-pointer)) (foreign-funcall "pthread_join" pthread-t (mem-ref th 'pthread-t) :pointer (null-pointer)))
We should at some point run it on the supported Lisps and note down which ones support this. Then add that information to the manual and possibly push something informative to *FEATURES* on Lisps that don't support this.