Created
July 25, 2008 17:01
-
-
Save chrismcg/2476 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Ruby Thread support: | |
Ruby implements threads by using setjmp/longjmp to switch between separate | |
C stacks within one native thread. | |
This confuses Objective C because NSThread stores a per-native-thread stack | |
of autorelease pools and exception handlers. When the C stack changes, an | |
error message like this is likely to appear: | |
Exception handlers were not properly removed. Some code has jumped or | |
returned out of an NS_DURING...NS_HANDLER region without using the | |
NS_VOIDRETURN or NS_VALUERETURN macros | |
The semantics of NSAutoreleasePools are also broken because the effective | |
scope crosses multiple threads. | |
The solution below requires a patch to the Ruby interpreter that implements | |
the following function: | |
void rb_add_threadswitch_hook(rb_threadswitch_hook_func_t func) | |
A hook is registered that multiplexes sets of autorelease pools and | |
exception stacks onto one NSThread. | |
Whenever a Ruby thread is switched in or out, the relevant context is saved | |
and restored. | |
Unfortunately, implementing this requires fiddling with two fields in the | |
NSThread internal structure. | |
A further complication arises due to the dynamic linker. Suppose RubyCocoa | |
has been linked against a patched libruby, but at runtime the user | |
accidentally uses /usr/bin/ruby (unpatched) to load RubyCocoa. Since | |
/usr/bin/ruby links to /usr/lib/libruby.dylib, and RubyCocoa links to | |
/path/to/patched/libruby.dylib, most of the functions will be picked up | |
from /usr/lib/libruby.dylib, but rb_add_threadswitch_hook will be linked | |
from the patched libruby.dylib. | |
The setup code explicitly determines the name of the libraries from which | |
two relevant symbols have been loaded from, and issues a warning and aborts | |
the setup process if they are different. | |
Tested on 10.4.7 PowerPC. | |
*/ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment