From: "Iñaki Baz Castillo" Date: 2012-04-24T19:47:16+09:00 Subject: Re: GVL lock and unlock 2012/4/17 Tony Arcieri : > On Tue, Apr 17, 2012 at 3:15 AM, Iñaki Baz Castillo 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: https://github.com/noderb/noderb (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. -- Iñaki Baz Castillo