From: MenTaLguY Date: 2007-12-11T09:15:21+09:00 Subject: Re: Compliment to rb_thread_blocking_region() ? On Tue, 11 Dec 2007 08:31:52 +0900, "Tony Arcieri" wrote: > On Dec 10, 2007 3:49 PM, MenTaLguY wrote: >> 1. Ruby would need some way to safely unwind the stack past the native >> code that (re-)entered the interpreter (e.g. due to a raised exception, >> throw, thread kill, etc.) > > How would it be different from what rb_funcall() does already? It's kind of the same problem. It isn't safe to call rb_funcall() directly from a C library's callback because it can mess up the C library's state if something raises/throws/kills from the Ruby side. I don't think it'd be a good idea to add an API explicitly to facilitate that kind of usage unless there were a way to make it safe. > Well, the goal with something like libevent would be to start inside Ruby, > set up a callback receiver object, and pass a handle to that callback > receiver object to the blocking call in the native extension. The native > extension would then block for the duration of libevent's loop running > (e.g. until something told it to stop), then have the libevent callbacks > make rb_funcall()s to the original callback object from Ruby. Right .. what I'm suggesting is that you call event_base_loop() with EVLOOP_ONCE from your own loop rather than using event_base_dispatch(). If you do that, you can perform the rb_funcall() after each event_base_loop() completes and the GIL has been re-acquired. The "real" libevent callback just needs to record the arguments it got somewhere so you know what pass to rb_funcall() later. -mental