[racket-dev] Problem with threads in Racket C API?

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Wed Oct 13 08:32:46 EDT 2010

At Tue, 12 Oct 2010 21:17:45 -0700, Justin Phillips wrote:
> I have a function that gets called by OS X's CoreMIDI framework. This
> function adds some data to a queue. I have registered the queue and the
> function with scheme_add_evt and scheme_add_evt_through_sema and even
> explicitly tried to block with scheme_block_until on separate occasions. In
> all instances, when the function gets called from CoreMIDI to add to my
> queue DrRacket dies because of EXC_BAD_ACCESS -- KERN_PROTECTION_FAILURE at
> 0x00 and the thread that crashed is the highest numbered thread (which is
> the DrRacket main thread no?) and it is in my function code. Am I setting
> something up wrong or could there be an issue with CoreMIDI? Any help would
> be greatly appreciated.

The lowest-numbered thread is normally the DrRacket main thread, so it
sounds like a thread mismatch is the likely the problem.

With a thread mismatch in 3m-cooperating code, you would get a crash
almost immediately, because the thread-local table identifying the GC
instance won't be there. If your callback is not using any Racket
functions, then annotate the function with `XFORM_SKIP_PROC', like

  void my_callback_in_wrong_thread(int arg)

The `XFORM_SKIP_PROC' annotation tells the 3m-cooperation transformer
to leave the function alone.

If your callback is using Racket functions, then you have to change it
so that's not the case. Although it sounds like you're not using
`ffi/unsafe', you might be able to use it to help bridge threads. If
you pass a callback to a foreign library where the callback will be
invoked in a thread other than the main one, the `#:async-apply' option
of `_fun' avoids the thread mismatch by sending the Racket callback
back to the main thread for invocation.

Posted on the dev mailing list.