Why can't ruby be used from a (native) thread other than the main one?

Hello,
Yesterday I was assisting in writing the server for a multiplayer gladiatorial combat game that embeds ruby. This server has an MFC gui that spawns a single hi-priority thread that runs all our game logic (this is what we are doing with ruby). However when ruby is initialised from the child thread and only used from that child thread it segfaults strait away. As soon as the ruby initialisation and code was moved back to the main thread it worked.
Has anyone found a way to work around this? We were using ruby-1.6.6 built with MSVC6 service pack 5. I will try with 1.6.7 on monday. I have not tried this sort of thing on linux.
Our attempt to work around it involved making the game logic run in a separate process, started with IO#popen, and communicate between the two processes using pipes, however IO#getc and other similar methods are blocking instead of returning nil when there is no data in the pipe, and select() with a timeout of 0 is doing exactly the same thing (i.e. blocking). I guess this is a “feature” of the unix-emulation used by the msvc port of ruby. I’m thinking of getting the FILE*'s out of the IO instance, and polling them (from c++) with a native thread. But this is rather messy, and a cleaner solution would be nice.
Also I’d like to add my voice to the request to be able to shutdown and re-initialise the ruby interpreter from c/c++.

Thanks,
Lorien Dunn

Lorien Dunn wrote:

Hello,
Yesterday I was assisting in writing the server for a multiplayer gladiatorial combat game that embeds ruby. This server has an MFC gui that spawns a single hi-priority thread that runs all our game logic (this is what we are doing with ruby). However when ruby is initialised from the child thread and only used from that child thread it segfaults strait away. As soon as the ruby initialisation and code was moved back to the main thread it worked.
Has anyone found a way to work around this? We were using ruby-1.6.6 built with MSVC6 service pack 5. I will try with 1.6.7 on monday. I have not tried this sort of thing on linux.
Our attempt to work around it involved making the game logic run in a separate process, started with IO#popen, and communicate between the two processes using pipes, however IO#getc and other similar methods are blocking instead of returning nil when there is no data in the pipe, and select() with a timeout of 0 is doing exactly the same thing (i.e. blocking). I guess this is a “feature” of the unix-emulation used by the msvc port of ruby. I’m thinking of getting the FILE*'s out of the IO instance, and polling them (from c++) with a native thread. But this is rather messy, and a cleaner solution would be nice.
Also I’d like to add my voice to the request to be able to shutdown and re-initialise the ruby interpreter from c/c++.

Thanks,
Lorien Dunn

.

For your information I have posted in bug this morning (Sep 13th,
2002) which strongly relates to what you describe. The blocking read
on Windows when used in a thread also had the side effect of blocking
all other running threads :frowning:

See http://www.ruby-lang.org/cgi-bin/ruby-bugs/incoming?id=401 for the
bug report. Nobu Nakada commented that this is a known but pending
bug. He also suggest what I think is a workaround in its follow-up
comment but not being a Win32 developer I’m not sure what it means
exactly.

I really hope this will be fixed soon because it also impacts our
project (FreeRIDE - the cross platform Ruby IDE - http://www.rubyide.org)

Laurent

Thanks Laurent,
however I can’t access that page. I just get :

Ruby Bug Tracking System
Ruby Search
The system encountered a fatal error
can’t get info in view_message

And I can't find msg id 401 :(. Could you perhaps forward me the work around suggested by nobu?
And FreeRIDE looks as though it is going to be very cool.

Thanks,
Lorien Dunn

···

On Fri, 13 Sep 2002 23:01:04 +0900 Laurent Julliard Laurent.Julliard@xrce.xerox.com wrote:

For your information I have posted in bug this morning (Sep 13th,
2002) which strongly relates to what you describe. The blocking read
on Windows when used in a thread also had the side effect of blocking
all other running threads :frowning:

See http://www.ruby-lang.org/cgi-bin/ruby-bugs/incoming?id=401 for the
bug report. Nobu Nakada commented that this is a known but pending
bug. He also suggest what I think is a workaround in its follow-up
comment but not being a Win32 developer I’m not sure what it means
exactly.

I really hope this will be fixed soon because it also impacts our
project (FreeRIDE - the cross platform Ruby IDE - http://www.rubyide.org)

Laurent

Oops,
I made it to the page. I don’t know what was going wrong. From Nobu’s reply:

Now 1.7 deals with non-blocking IO, so WSAEventSelect() and
MsgWaitForMultipleObjects() solution may be acceptable.

I don't know about WSAEventSelect(), but MsgWaitForMultipleObjects() is the equivalent of the select() call on unix. However as far as I can tell it doesn't work on pipes!

One possible solution could be to use sockets instead of pipes, because micro$oft just ripped the bsd sockets code and put it in windoze. As a result, sockets are the only type that support the unix select() call. However i doubt ruby exploits this "feature" of windoze.
···

On Sat, 14 Sep 2002 08:09:35 +0900 Lorien Dunn loriend@bigpond.com wrote:

Thanks Laurent,
however I can’t access that page. I just get :

Ruby Bug Tracking System
Ruby Search
The system encountered a fatal error
can’t get info in view_message

And I can’t find msg id 401 :(. Could you perhaps forward me the work around suggested by nobu?
And FreeRIDE looks as though it is going to be very cool.

Thanks,
Lorien Dunn