2012/4/17 Tony A. [email protected]:
On Tue, Apr 17, 2012 at 3:15 AM, Iñaki Baz C. [email protected] wrote:
BTW: During the libuv event loop, Ruby callbacks will be called.
Should I take the GVL before invoking them?
Yes, definitely, you want to have the GVL released for as little time as
possible, and when it is released you should only be doing things in memory
you allocated yourself from C.
Ok, so in summary:
-
I must release the GVL before running the uv loop (which is a
blocking function that just returns when there are no listeners in the
loop). If not, other Ruby threads cannot work (already verified).
-
And I must take again the GVL when a uv callback occurs (i.e. a
timer) and I must execute some associated Ruby code (i.e. a
block.call), and then I must release again the GVL after such a Ruby
code terminates so uv takes again the control and the GVL is released
for other Ruby threads to work.
Am I right?
I ran into similar problems with rb_thread_blocking_region() writing a
wrapper for libev (well, twice now, once with cool.io and once with nio4r)
as its API mandates a function pointer, as opposed to the sort
of GVL_UNLOCK_BEGIN/END macros that you would expect. This is a problem,
because the libev API provides before/after callbacks that happen around the
system call (e.g. epoll) that would be great for unlocking and relocking the
GVL.
I found similar issues and similar complains by reading some threads.
I understand this API was not provided because it was considered too
dangerous, but it was really needed for libev. I wonder if you’ll encounter
the same problems with libuv. I really wish there were a
GVL_EXTREMELY_DANGEROUS_USE_WITH_CARE_UNLOCK_BEGIN/END macro
Probably yes since uv (when compiled on Linux) is a wrapper of libev
I ended up having to patch the libev source code and put
rb_thread_blocking_region() right into the heart of the event loop.
Annoying! I think I will advance a bit more in my code (for now
“single Ruby thread” XD) and I will care about this stuff later.
BTW, what kind of wrapper are you doing for libuv? Are you going for a
comprehensive one, or only wrapping part of the functionality?
A comprehensive one. First I took a look to this non mantained project:
GitHub - noderb/noderb: NodeRb = NodeJs - JavaScript + Ruby
(there are thinks that are not very correct there, but it’s nice for
an initial approach).
I’d love to add libuv into the next release of nio4r (it already uses libev
for a selector API).
libuv uses libev, so what would be the purpose?
libuv could be used to do direct buffers on the C side
the same way Java NIO can do them on the Java side.
I need to go deeper into the libuv API in order to understand what you
mean
Thanks a lot.