[Rubycocoa-devel 374] Updated thread hook patches

Back to archive index

Jonathan Paisley jp-ww****@dcs*****
Thu Aug 24 07:08:20 JST 2006


Hi all,

I've attached to this message the latest update to my Ruby Thread  
patches for RubyCocoa.

The patches come in two parts:

  (1) ruby-thread-hooks.patch

      This is a patch to the 1.8.5pre interpreter (also should work  
on 1.8.4)
      that adds an exported function called 'rb_add_threadswitch_hook'.

  (2) rubycocoa-threads.patch

      This is a patch to RubyCocoa (apply to trunk with my xcodeproj  
updates)
      that adds the RubyCocoa code to talk to those patches.

      If the Ruby interpreter hasn't been patched, RubyCocoa should  
still build and
      work as it did before.

Patch (2) overrides Thread.new to raise an exception if runtime  
thread support is not present.

I've added a test file that exercises the code: test/tc_thread.rb.  
There are some comments in there that explain what it's doing, and  
you can try running the tests with a non-patched interpreter to see  
the nasty crashes that occur.

I've pasted below an extracted comment from RBRuntime.m.

Cheers,
Jonathan



/* 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.
  */


-------------- next part --------------
A non-text attachment was scrubbed...
Name: ruby-thread-hooks.patch
Type: application/octet-stream
Size: 3322 bytes
Desc: not available
Url : http://lists.sourceforge.jp/mailman/archives/rubycocoa-devel/attachments/20060823/eb80d7b3/attachment.obj 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: rubycocoa-threads.patch
Type: application/octet-stream
Size: 26262 bytes
Desc: not available
Url : http://lists.sourceforge.jp/mailman/archives/rubycocoa-devel/attachments/20060823/eb80d7b3/attachment-0001.obj 


More information about the Rubycocoa-devel mailing list
Back to archive index