[Kde-bindings] Using threads with QtRuby

Uriel uriel at inbox.ru
Sun Feb 7 17:16:24 UTC 2010

I've done some debuging on QtRuby and GtkRuby and it seems that I've 
found the problem and the trick GtkRuby uses.
I absolutely don't know how does glib works and why does the following 
solution work but all the magic is in custom poll function.
GtkRuby's poll function interacts directly with Ruby's threads mechanism 
and doing something with blocking regions.

So here is the result of my "research". I've compiled the following code 
as a shared library:

#include <glib.h>
#include <ruby.h>

static GPollFunc default_poll_func;

typedef struct _PollInfo
     GPollFD *ufds;
     guint nfsd;
     gint timeout;
     gint result;
} PollInfo;

static VALUE
rg_poll_in_blocking(void *data)
     PollInfo *info = data;

     info->result = default_poll_func(info->ufds, info->nfsd, 

     return Qnil;

static gint
rg_poll(GPollFD *ufds, guint nfsd, gint timeout)
     PollInfo info;

     info.ufds = ufds;
     info.nfsd = nfsd;
     info.timeout = timeout;
     info.result = 0;

     rb_thread_blocking_region(rg_poll_in_blocking, &info, RUBY_UBF_IO, 

     return info.result;

void foo() {
   default_poll_func = g_main_context_get_poll_func(NULL);
   g_main_context_set_poll_func(NULL, rg_poll);

And then, in ruby program, called this function like this:

require 'dl/func'

lib = DL.dlopen './foo.so'
cfunc = DL::CFunc.new lib['foo'], DL::TYPE_VOID
func = DL::Function.new cfunc, []


After this call threads began to work. And by the way, when I was using 
the workaround from the previous message my test thread finished in 17 
seconds time. But with custom poll function it finish just in 2-3 seconds.

That's just the simple illustration of an idea. Full GtkRuby's file 
contains some preprocessor conditions for Ruby 1.8 and Ruby 1.9 and you 
can be interested in looking at it. This file can be found at 
and it's called `glib/src/rbglib_maincontext.c`.

More information about the Kde-bindings mailing list