# C extension and Ruby threads

**URL:** <https://www.ruby-forum.com/t/c-extension-and-ruby-threads/172698>\
**Category:** Ruby\
**Created:** [July 26, 2009, 12:18am UTC](https://www.ruby-forum.com/t/c-extension-and-ruby-threads/172698 "2009-07-26T00:18:06Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![johnnybutler7](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/8491ac/32.png) [@johnnybutler7](https://www.ruby-forum.com/u/johnnybutler7)\
**Post date:** [July 26, 2009, 12:18am UTC](https://www.ruby-forum.com/t/c-extension-and-ruby-threads/172698/1 "2009-07-26T00:18:06Z")

</div>

Hi all,  
I’ve found something a bit weird while trying to make a C extension  
wrapping a custom network library :

- My extension creates a BaseClient class with a method ‘receive’ (it  
basically wait a response from a server for a given period of time)
- I created a ruby class Client that inherits from BaseClient. In the  
constructor of this class, I create a thread that loops on the method  
receive(). Note that in my C code, the receive function does a  
WaitForSingleObject (Windows equivalent of pthread\_cond\_wait ) with a  
timeout of 100ms

My problem is that even if my reception thread is in a wait state, my  
main thread doesn’t run smoothly (it freezes while the other thread  
calls Client#receive).  
I tried to place a Thread.pass between each iteration of the loop,  
that’s a little better but still far from what I expected.

Tested on Ruby 1.8.7 and ruby 1.9.1 (thought that native threads would  
solve my problem, but not at all).

My code is the following :

require ‘TestClientBase’  
class Client \< ClientBase

```
  def initialize()
    @thread = Thread.new(self) {
      |client|
      fin = false
      while fin != true
       msg = client.receive(100)
       case msg
        when TIME_OUT
           puts ("Timeout")
        when SERV_CLOSED
           fin = true
       end
       Thread.pass
      end
    }
    @thread.priority = -1
  end
  def wait()
      @thread.join(10.0)
  end

```

end

client = Client.new

100.times {  
puts “Time=#{Time.now}”  
}

client.wait()

Thanks for you replies.

---

<div class="post-metadata">

**Author:** ![johnnybutler7](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/8491ac/32.png) [@johnnybutler7](https://www.ruby-forum.com/u/johnnybutler7)\
**Post date:** [July 26, 2009, 2:03am UTC](https://www.ruby-forum.com/t/c-extension-and-ruby-threads/172698/2 "2009-07-26T02:03:33Z")

</div>

On Sun, 2009-07-26 at 07:18 +0900, John Bob wrote:

> - I created a ruby class Client that inherits from BaseClient. In the  
> constructor of this class, I create a thread that loops on the method  
> receive(). Note that in my C code, the receive function does a  
> WaitForSingleObject (Windows equivalent of pthread\_cond\_wait ) with a  
> timeout of 100ms

In 1.8, there’s not really a good way to address this unless you can  
convert the object you’re waiting on to a file descriptor suitable to  
wait on with rb\_thread\_select().

In 1.9, there is additionally an API function –  
rb\_thread\_blocking\_region – which you can use to wrap a function which  
needs to block (provided that the function doesn’t touch the Ruby  
interpreter or Ruby objects in any way); rb\_thread\_blocking\_region  
permits other threads to continue while the function you pass to it  
blocks.

Either approach should also permit you to simply block without polling  
with a timeout as you do now.

-mental

---

<div class="post-metadata">

**Author:** ![johnnybutler7](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/8491ac/32.png) [@johnnybutler7](https://www.ruby-forum.com/u/johnnybutler7)\
**Post date:** [July 26, 2009, 1:55pm UTC](https://www.ruby-forum.com/t/c-extension-and-ruby-threads/172698/3 "2009-07-26T13:55:46Z")

</div>

On Sun, Jul 26, 2009 at 9:01 AM, MenTaLguY[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> On Sun, 2009-07-26 at 07:18 +0900, John Bob wrote:
> 
> > - I created a ruby class Client that inherits from BaseClient. In the  
> > constructor of this class, I create a thread that loops on the method  
> > receive(). Note that in my C code, the receive function does a  
> > WaitForSingleObject (Windows equivalent of pthread\_cond\_wait ) with a  
> > timeout of 100ms

How about rb\_thread\_polling() and WaitForSingleObject(handle, 0)?

while ((result = WaitForSingleObject(handle, 0)) == WAIT\_TIMEOUT) {  
/\* The current thread sleeps 0.06 second to make a time for other  
threads to run. \*/  
rb\_thread\_polling();  
}  
if (result == WAIT\_OBJECT\_0) {  
…

> In 1.8, there’s not really a good way to address this unless you can  
> convert the object you’re waiting on to a file descriptor suitable to  
> wait on with rb\_thread\_select().

rb\_thread\_select() is best for file descriptors on Unix. But on Windows,  
it works only for sockets. It assumes normal files are always  
readable/writable.  
See a comment in rb\_w32\_select() in win32/win32.c. Thus it is unusable  
in  
this case.

> In 1.9, there is additionally an API function –  
> rb\_thread\_blocking\_region – which you can use to wrap a function which  
> needs to block (provided that the function doesn’t touch the Ruby  
> interpreter or Ruby objects in any way); rb\_thread\_blocking\_region  
> permits other threads to continue while the function you pass to it  
> blocks.

Agree. It is better than rb\_thread\_polling() in 1.9.

---

<div class="post-metadata">

**Author:** ![johnnybutler7](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/8491ac/32.png) [@johnnybutler7](https://www.ruby-forum.com/u/johnnybutler7)\
**Post date:** [July 26, 2009, 2:50pm UTC](https://www.ruby-forum.com/t/c-extension-and-ruby-threads/172698/4 "2009-07-26T14:50:05Z")

</div>

Takehiro Kubo wrote:

> On Sun, Jul 26, 2009 at 8:47 PM, KUBO Takehiro[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > How about rb\_thread\_polling() and WaitForSingleObject(handle, 0)?
> 
> Sorry, rb\_thread\_polling() returns immediately if only one thread runs.  
> rb\_thread\_wait\_for() should be used instead.
> 
> while ((result = WaitForSingleObject(handle, 0)) == WAIT\_TIMEOUT) {  
> struct timeval tv;  
> tv.sec = 0;  
> tv.usec = 100000;  
> rb\_thread\_wait\_for(rv); /\* sleep 0.1 second \*/  
> }

I used the rb\_thread\_blocking\_region method, seems to work like a charm!  
Thanks a lot for your help.

---

<div class="post-metadata">

**Author:** ![johnnybutler7](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/8491ac/32.png) [@johnnybutler7](https://www.ruby-forum.com/u/johnnybutler7)\
**Post date:** [July 26, 2009, 2:01pm UTC](https://www.ruby-forum.com/t/c-extension-and-ruby-threads/172698/5 "2009-07-26T14:01:02Z")

</div>

On Sun, Jul 26, 2009 at 8:47 PM, KUBO Takehiro[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> How about rb\_thread\_polling() and WaitForSingleObject(handle, 0)?

Sorry, rb\_thread\_polling() returns immediately if only one thread runs.  
rb\_thread\_wait\_for() should be used instead.

while ((result = WaitForSingleObject(handle, 0)) == WAIT\_TIMEOUT) {  
struct timeval tv;  
tv.sec = 0;  
tv.usec = 100000;  
rb\_thread\_wait\_for(rv); /\* sleep 0.1 second \*/  
}
