How to call Ruby from non-interpreter native thread?

  • Thread starter -= Ko =- Black Ninja
  • Start date
K

-= Ko =- Black Ninja

Hi everybody,

i start using Ruby interpreter and wrote some Ruby extension on C++ on
Win32 platform. I embedded Ruby extension with SWIG. So my extension
provide some communication capabilities, i.e. create server endpoint and
wait for messages. If in extension i make WaitForSingleObject() or
another blocking operation that will block interpreter thread, if i call
method from Ruby, which implement block operation. Besides, i run some
parallel Ruby threads, which are blocked too.

So, i can't receive messages synchronous and have to use asynchronous
mechanism. Thus, i create new native by CreateThread() (non-interpreter
native thread), when i call Run() method of my extension class. And no
blocks occur, control return to Ruby interpreter thread.

Below is a part of my Ruby code, that starts new thread, which starts
new server and listen for messages. RubyCallback is my extension class,
that implement callback interface from C++ into Ruby. RubyCallback class
has call() method, which call rb_funcall() function. If no messages
arrived then receiver_thread will suspend until new message arrives and
callback resume the thread, that start Receive() method.

receiver_thread = Thread.new do
cb = RubyCallback::RubyCallback.new(Thread.current, "wakeup")

ccinit = InterComm::CC_INIT.new
ccinit.pAlertObject = cb #register callback

cc = InterComm::Communication.new
ret = cc.Init(ccinit)
if (ret)
puts "InterComm INIT OK"
end
ret = cc.Run() # here new native listener thread starts
if (ret)
puts "InterComm RUN OK"
end

loop do
mess = cc.Receive()
if (mess == nil)
puts "not Receive, fall a sleep...\n"
Thread.stop # thread self suspended if
# no new messages arrived
else
puts mess.MessageData
end
end

end

When new message arrived extension call callback function from Ruby to
say, that extension have new message. I implement C-Ruby callback
interface and call rb_funcall(...), but application starts to work very
strange: very seldom it works well just for one time, but often it may
crashed or deadlock in rb_funcall() call.

I know that Ruby interpreter isn't thread safe. Advice me how to
properly call Ruby function from C in interpreter thread context from
non-interpreter native thread? Or how can i schedule or queued call Ruby
function in properly way?

Thanx in advance!
 
K

-= Ko =- Black Ninja

I've got skill with GIL (Global Interpreter Lock) and used
rb_thread_blocking_region() function. So, this thread can be close
now...

thanx to myself =))
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,525
Members
44,997
Latest member
mileyka

Latest Threads

Top