[Patch] handle glib signals coming from different threads


#1

Hi,

With stuff like gstreamer it’s possible that signals originate from
(native)
threads that are different from ruby’s native thread.

Currently the signal marshaller always enters the ruby interpreter to
handle
signals even if it’s not run in ruby’s native thread. Leading to all
kinds of
interesting crashes.

The following patch solves this as follows:
On intialization it creates a pipe and a ruby thread watching it
(the
marshal_pop thread).

Now when a signal is marshalled in a non-native thread, the 

marshaller
puts all signal info in a shared variable and writes one byte
into the pipe. When the marshal_pop thread sees this, it will run
the
actuall callback in ruby’s native thread. Obviously there is some
locking
going on, see the code for more details.

Conceptually this means that the thread that emitted the signal and
ruby’s
native thread are temporary synchronized while the callback is run.
Which
quite effectively fixes the crashes i’ve been seeing.

Note that this give some risk for deadlocks as the signal emition can
only
finish when the ruby thread can run (i.e. not while your waiting in
some C
code). A good example of this is letting gstreamer wait on a state
change
for an element, while that state changes only happens after a certain
(ruby)
callback has been run…

I’ve also attached a small silly program (avtest) that crashes without
this
patch, but works fine with it.

Sjoerd