Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Ruby (http://www.velocityreviews.com/forums/f66-ruby.html)
-   -   How to call Ruby from non-interpreter native thread? (http://www.velocityreviews.com/forums/t866782-how-to-call-ruby-from-non-interpreter-native-thread.html)

-= Ko =- Black Ninja 04-01-2011 08:32 AM

How to call Ruby from non-interpreter native thread?
 
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!

--
Posted via http://www.ruby-forum.com/.


-= Ko =- Black Ninja 04-05-2011 07:31 AM

Re: How to call Ruby from non-interpreter native thread?
 
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 =))

--
Posted via http://www.ruby-forum.com/.



All times are GMT. The time now is 02:02 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.