# Ruby thread feat. win32 message cycle

**URL:** <https://www.ruby-forum.com/t/ruby-thread-feat-win32-message-cycle/96603>\
**Category:** Ruby\
**Created:** [June 30, 2006, 3:34am UTC](https://www.ruby-forum.com/t/ruby-thread-feat-win32-message-cycle/96603 "2006-06-30T03:34:11Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Victor\_SZverokS\_She](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/46a35a/32.png) [@Victor\_SZverokS\_She](https://www.ruby-forum.com/u/Victor_SZverokS_She)\
**Post date:** [June 30, 2006, 3:34am UTC](https://www.ruby-forum.com/t/ruby-thread-feat-win32-message-cycle/96603/1 "2006-06-30T03:34:11Z")

</div>

Hi all.  
I’ve tried the simple code:

Thread.new{ runMessageCycle}  
puts ‘here’

where runMessageCycle is a simple C extension method with Win32 message  
cycle:

static VALUE run(VALUE \_self)  
{  
MSG msg;  
while (::GetMessage(&msg, NULL, 0, 0))  
{  
::TranslateMessage(&msg);  
::DispatchMessage(&msg);  
}

```
return _self;

```

}

I’m very surprised that Thread.new don’t returns (“here” will be never  
printed).  
What is silly with my code?

Thanks,  
Victor.

---

<div class="post-metadata">

**Author:** ![Victor\_SZverokS\_She](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/46a35a/32.png) [@Victor\_SZverokS\_She](https://www.ruby-forum.com/u/Victor_SZverokS_She)\
**Post date:** [June 30, 2006, 4:32am UTC](https://www.ruby-forum.com/t/ruby-thread-feat-win32-message-cycle/96603/2 "2006-06-30T04:32:45Z")

</div>

My guess would be that runMessageCycle never returns (until the while  
loop  
breaks, anyway) so Ruby never gets a chance to execute any more code.  
The C  
code in the extension doesn’t know anything about Ruby’s thread  
scheduler. I  
haven’t tried this, but what if you called rb\_thread\_select with an  
empty  
descriptor set on each pass through the while loop?

---

<div class="post-metadata">

**Author:** ![Victor\_SZverokS\_She](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/46a35a/32.png) [@Victor\_SZverokS\_She](https://www.ruby-forum.com/u/Victor_SZverokS_She)\
**Post date:** [June 30, 2006, 5:01am UTC](https://www.ruby-forum.com/t/ruby-thread-feat-win32-message-cycle/96603/3 "2006-06-30T05:01:20Z")

</div>

From: Francis C. [[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)]  
Sent: Friday, June 30, 2006 5:29 AM

> I  
> haven’t tried this, but what if you called rb\_thread\_select with an empty  
> descriptor set on each pass through the while loop?

BTW, where can I find simple examples of usage of rb\_thread\_select. I’m  
very-very not familiar with it ☹

V.

---

<div class="post-metadata">

**Author:** ![Victor\_SZverokS\_She](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/46a35a/32.png) [@Victor\_SZverokS\_She](https://www.ruby-forum.com/u/Victor_SZverokS_She)\
**Post date:** [June 30, 2006, 4:51am UTC](https://www.ruby-forum.com/t/ruby-thread-feat-win32-message-cycle/96603/4 "2006-06-30T04:51:01Z")

</div>

From: Francis C. [[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)]  
Sent: Friday, June 30, 2006 5:29 AM

> > }
> > 
> > I’m very surprised that Thread.new don’t returns (“here” will be never  
> > printed).  
> > What is silly with my code?  
> > My guess would be that runMessageCycle never returns (until the while loop  
> > breaks, anyway) so Ruby never gets a chance to execute any more code.

Yes, It never returns. But I’ve thought its not a problem, because in  
the  
code:  
Thread.new{ sleep(10000) }  
puts ‘here’  
sleep(10000) also virtually never returns, but code works as expected  
(prints ‘here’ and exits).

> The C  
> code in the extension doesn’t know anything about Ruby’s thread scheduler.  
> I  
> haven’t tried this, but what if you called rb\_thread\_select with an empty  
> descriptor set on each pass through the while loop?

Hmmm… Ok, I’ll try. But I think there must be more general solution  
for  
threading C extension. No?

V.

---

<div class="post-metadata">

**Author:** ![Victor\_SZverokS\_She](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/46a35a/32.png) [@Victor\_SZverokS\_She](https://www.ruby-forum.com/u/Victor_SZverokS_She)\
**Post date:** [June 30, 2006, 5:31am UTC](https://www.ruby-forum.com/t/ruby-thread-feat-win32-message-cycle/96603/5 "2006-06-30T05:31:38Z")

</div>

On 6/29/06, Victor ‘Zverok’ Shepelev [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> BTW, where can I find simple examples of usage of rb\_thread\_select. I’m  
> very-very not familiar with it ☹  
> \<\<\<\<\<\<\<\<\<\<\<\<

None that I’m aware of. If you can’t find anything easier, look in the  
source code of EventMachine (grep in the .h files).

---

<div class="post-metadata">

**Author:** ![Victor\_SZverokS\_She](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/46a35a/32.png) [@Victor\_SZverokS\_She](https://www.ruby-forum.com/u/Victor_SZverokS_She)\
**Post date:** [June 30, 2006, 5:31am UTC](https://www.ruby-forum.com/t/ruby-thread-feat-win32-message-cycle/96603/6 "2006-06-30T05:31:29Z")

</div>

On 6/29/06, Victor ‘Zverok’ Shepelev [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Yes, It never returns. But I’ve thought its not a problem, because in the  
> code:  
> Thread.new{ sleep(10000) }  
> puts ‘here’  
> sleep(10000) also virtually never returns, but code works as expected  
> (prints ‘here’ and exits).  
> \<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<

sleep(10000) is a Ruby call, not a native one. It’s aware that other  
Ruby  
threads are running. Try doing the same thing on your native thread with  
a  
native API (I forget what that millisecond-sleep API is on Windows)-  
you’ll  
find that it blocks your program just as the event loop did.

> > > > Hmmm… Ok, I’ll try. But I think there must be more general solution  
> > > > for  
> > > > threading C extension. No?\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<

You’re wandering into the strange land of native/green thread  
interaction. I  
won’t be the one to start yet another rehash of this subject ;-). If  
you’re  
trying to run the Windows GUI event loop, why not just use Ruby tk?

---

<div class="post-metadata">

**Author:** ![Victor\_SZverokS\_She](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/46a35a/32.png) [@Victor\_SZverokS\_She](https://www.ruby-forum.com/u/Victor_SZverokS_She)\
**Post date:** [June 30, 2006, 5:37am UTC](https://www.ruby-forum.com/t/ruby-thread-feat-win32-message-cycle/96603/7 "2006-06-30T05:37:46Z")

</div>

From: Francis C. [[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)]  
Sent: Friday, June 30, 2006 6:29 AM

> sleep(10000) is a Ruby call, not a native one. It’s aware that other Ruby  
> threads are running. Try doing the same thing on your native thread with a  
> native API (I forget what that millisecond-sleep API is on Windows)-  
> you’ll  
> find that it blocks your program just as the event loop did.

OK, I’ve got it.

> > > > > Hmmm… Ok, I’ll try. But I think there must be more general solution  
> > > > > for  
> > > > > threading C extension. No?\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<
> 
> You’re wandering into the strange land of native/green thread interaction.  
> I  
> won’t be the one to start yet another rehash of this subject ;-). If  
> you’re  
> trying to run the Windows GUI event loop, why not just use Ruby tk?

Because I’m doing my own GUI library :)))  
BTW, here is the solution of my problem (and thank you, the solution was  
very close to your advice!):  
static VALUE run(VALUE \_self)  
{  
MSG msg;  
while (1)  
{  
::PeekMessage(&msg, NULL, 0, 0, PM\_REMOVE); //the 1st  
gotcha! We need Peek, not Get message  
::TranslateMessage(&msg);  
::DispatchMessage(&msg);  
if(msg.message == WM\_QUIT) break;  
rb\_thread\_schedule(); //second gotcha! Give ruby’s scheduler  
the possibility to switch  
}

```
return _self;

```

}

V.

---

<div class="post-metadata">

**Author:** ![Victor\_SZverokS\_She](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/46a35a/32.png) [@Victor\_SZverokS\_She](https://www.ruby-forum.com/u/Victor_SZverokS_She)\
**Post date:** [June 30, 2006, 6:20am UTC](https://www.ruby-forum.com/t/ruby-thread-feat-win32-message-cycle/96603/8 "2006-06-30T06:20:04Z")

</div>

Put some printfs in the C code - I think you’ll find it never gets out  
of  
GetMessage. If your thread has no windows it may have no events… or  
it it  
returns a negative value you’ll stay in the loop as long as it gets  
errors.

good luck!  
JB

---

<div class="post-metadata">

**Author:** ![Victor\_SZverokS\_She](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/46a35a/32.png) [@Victor\_SZverokS\_She](https://www.ruby-forum.com/u/Victor_SZverokS_She)\
**Post date:** [June 30, 2006, 6:26am UTC](https://www.ruby-forum.com/t/ruby-thread-feat-win32-message-cycle/96603/9 "2006-06-30T06:26:18Z")

</div>

From: John B. [[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)]  
Sent: Friday, June 30, 2006 7:19 AM

> > }
> > 
> > I’m very surprised that Thread.new don’t returns (“here” will be never  
> > printed).  
> > Put some printfs in the C code - I think you’ll find it never gets out of  
> > GetMessage. If your thread has no windows it may have no events… or it  
> > it  
> > returns a negative value you’ll stay in the loop as long as it gets  
> > errors.

I’ve already found the solution. In fact, there were 2 errors:

1. I had to use PeekMessage instead of GetMessage
2. I had to do rb\_thread\_schedule() to let Ruby’s scheduler to switch  
threads.

V.
