Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.ruby > #2098 > unrolled thread

How to call Ruby from non-interpreter native thread?

Started by-= Ko =- Black Ninja <sungurik@rambler.ru>
First post2011-04-01 03:32 -0500
Last post2011-04-05 02:31 -0500
Articles 2 — 1 participant

Back to article view | Back to comp.lang.ruby


Contents

  How to call Ruby from non-interpreter native thread? -= Ko =- Black Ninja <sungurik@rambler.ru> - 2011-04-01 03:32 -0500
    Re: How to call Ruby from non-interpreter native thread? -= Ko =- Black Ninja <sungurik@rambler.ru> - 2011-04-05 02:31 -0500

#2098 — How to call Ruby from non-interpreter native thread?

From-= Ko =- Black Ninja <sungurik@rambler.ru>
Date2011-04-01 03:32 -0500
SubjectHow to call Ruby from non-interpreter native thread?
Message-ID<3d387397bafae9b859872a3f17cb679c@ruby-forum.com>
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/.

[toc] | [next] | [standalone]


#2301

From-= Ko =- Black Ninja <sungurik@rambler.ru>
Date2011-04-05 02:31 -0500
Message-ID<49bf6e4814c28b440e2c22fefe2d95dd@ruby-forum.com>
In reply to#2098
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/.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.ruby


csiph-web