# Waking ruby thread on external event

**URL:** <https://www.ruby-forum.com/t/waking-ruby-thread-on-external-event/75064>\
**Category:** Ruby\
**Created:** [March 1, 2006, 3:32am UTC](https://www.ruby-forum.com/t/waking-ruby-thread-on-external-event/75064 "2006-03-01T03:32:07Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![kelleysislander](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f6c823/32.png) [@kelleysislander](https://www.ruby-forum.com/u/kelleysislander)\
**Post date:** [March 1, 2006, 3:32am UTC](https://www.ruby-forum.com/t/waking-ruby-thread-on-external-event/75064/1 "2006-03-01T03:32:07Z")

</div>

Hi,

I have Ruby embedded into a multithreaded C++ app. It’s easy for  
a C++ thread to wait for an event from a Ruby thread.(\*) But I’m  
looking for ways to allow a Ruby thread to sleep until an event  
from a C++ thread is posted.

My application is cross-platform so my solution needs to work on  
Windows and OS X.

So far all I can think of, without hacking ruby itself, is to  
open a TCP or UDP socket, and have the Ruby thread select() on  
the socket. Then the C++ side can fire a packet at the socket to  
wake the ruby thread up.

Can anyone think of a simpler way? I haven’t measured the overhead  
yet, but offhand it seems overkill to send a packet through the IP  
stack to do the work of a condition variable. (But yes I do need  
to actually measure it.)

(\*) Sleeping in C++ for an event from a Ruby thread: The C++ thread  
sleeps on a boost::condition variable. The Ruby thread invokes a C  
extension method which notify()'s the condition variable. Simple  
enough in this direction.

Any thoughts appreciated,

Thanks,

Bill

---

<div class="post-metadata">

**Author:** ![kelleysislander](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f6c823/32.png) [@kelleysislander](https://www.ruby-forum.com/u/kelleysislander)\
**Post date:** [March 1, 2006, 3:37am UTC](https://www.ruby-forum.com/t/waking-ruby-thread-on-external-event/75064/2 "2006-03-01T03:37:37Z")

</div>

Bill K. wrote:

> (\*) Sleeping in C++ for an event from a Ruby thread: The C++ thread  
> sleeps on a boost::condition variable. The Ruby thread invokes a C  
> extension method which notify()'s the condition variable. Simple  
> enough in this direction.

Can’t you do this the other way around as well… write C/C++ extension  
for ruby which stores  
reference to ruby thread, and call it from c++ code which would wake  
your ruby thread?

Zach

---

<div class="post-metadata">

**Author:** ![kelleysislander](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f6c823/32.png) [@kelleysislander](https://www.ruby-forum.com/u/kelleysislander)\
**Post date:** [March 1, 2006, 5:29am UTC](https://www.ruby-forum.com/t/waking-ruby-thread-on-external-event/75064/3 "2006-03-01T05:29:53Z")

</div>

Bill K. wrote:

> So far all I can think of, without hacking ruby itself, is to  
> open a TCP or UDP socket, and have the Ruby thread select() on  
> the socket. Then the C++ side can fire a packet at the socket to  
> wake the ruby thread up.
> 
> Can anyone think of a simpler way? I haven’t measured the overhead  
> yet, but offhand it seems overkill to send a packet through the IP  
> stack to do the work of a condition variable. (But yes I do need  
> to actually measure it.)

Can the ruby thread just Thread.sleep, and wait for the C++ code to call  
rb\_thread\_wakeup() or whatever it is that implements Thread#wakeup ?

---

<div class="post-metadata">

**Author:** ![kelleysislander](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f6c823/32.png) [@kelleysislander](https://www.ruby-forum.com/u/kelleysislander)\
**Post date:** [March 1, 2006, 6:19am UTC](https://www.ruby-forum.com/t/waking-ruby-thread-on-external-event/75064/4 "2006-03-01T06:19:43Z")

</div>

From: “zdennis” removed\_email\_address@domain.invalid

> for ruby which stores reference to ruby thread, and call it from c++ code  
> which would wake your ruby thread?

All ruby threads run on a single OS thread, and the ruby  
interpreter isn’t generally reentrant, as I understand it.

So I don’t know how to put one ruby thread to sleep on something  
like a boost::condition variable without sleeping the whole OS  
thread ruby runs on, thus blocking all ruby threads.

And I also don’t know if I can call straight into ruby’s eval.c  
from a non-ruby OS thread, to try to fiddle with the ruby threads  
and the ruby scheduler to wake my ruby thread up - due to the  
ruby interpreter not being reentrant. (Without hacking the ruby  
source code, at any rate.) Although if anyone knows to the  
contrary, that an external OS thread can safely wake up a  
ruby thread that’d be great.

I may end up trying the UDP approach. It’s got to be better  
than my initial make-it-work implementation, where my ruby  
threads sleep for 1/10 second and check a queue.

But if anybody knows another way … ? 🙂

Regards,

Bill

---

<div class="post-metadata">

**Author:** ![kelleysislander](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f6c823/32.png) [@kelleysislander](https://www.ruby-forum.com/u/kelleysislander)\
**Post date:** [March 1, 2006, 8:30am UTC](https://www.ruby-forum.com/t/waking-ruby-thread-on-external-event/75064/5 "2006-03-01T08:30:25Z")

</div>

From: “Joel VanderWerf” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

> Can the ruby thread just Thread.sleep, and wait for the C++ code to call  
> rb\_thread\_wakeup() or whatever it is that implements Thread#wakeup ?

Hi - somehow i’d not seen your reply. Thanks.

Hmm…

VALUE  
rb\_thread\_wakeup(thread)  
VALUE thread;  
{  
rb\_thread\_t th = rb\_thread\_check(thread);

```
if (th->status == THREAD_KILLED)
    rb_raise(rb_eThreadError, "killed thread");
rb_thread_ready(th);

return thread;

```

}

I don’t suppose this could be called from a different OS thread  
than ruby’s.

And the ruby interpreter may be waiting in a select() call when  
I need to wake up my ruby thread.

Ah, well… Maybe UDP is the way to go…

Regards,

Bill

---

<div class="post-metadata">

**Author:** ![kelleysislander](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f6c823/32.png) [@kelleysislander](https://www.ruby-forum.com/u/kelleysislander)\
**Post date:** [March 1, 2006, 8:53am UTC](https://www.ruby-forum.com/t/waking-ruby-thread-on-external-event/75064/6 "2006-03-01T08:53:24Z")

</div>

Bill K. wrote:

> rb\_thread\_wakeup(thread)
> 
> I don’t suppose this could be called from a different OS thread  
> than ruby’s.

Not necessarily such a problem. rb\_thread\_wakeup() doesn’t muck around  
with any data structures that the thread scheduler uses. It just sets a  
couple of fields in the thread object. So there’s a race condition, and  
a breaking of encapsulation, and a gnashing of teeth. But other than  
that, possible.

> And the ruby interpreter may be waiting in a select() call when  
> I need to wake up my ruby thread.

Oh. That’s the real problem. You could keep one thread in a loop {sleep  
epsilon}, but that’s back to square one.

> Ah, well… Maybe UDP is the way to go…

Sounds like it is.
