Rb_eval_string blocks on loops even if run inside a thread

Hey,

I’m trying to use rb_eval_string to execute a bunch of code and return
from
it straight away. My problem is that the code I want to eval contains a
continuous loop. Even if I wrap the code in a thread the call still
blocks
due to the loop. Note that I don’t get the same behaviour when using
eval()
outside of the C API.

E.g:

rb_eval_string(“Thread.new { loop { puts 1; sleep 0.2 }}”); <-- blocks
eval(“Thread.new { loop { puts 1; sleep 0.2 }}”) <— doesn’t block

My guess is to spawn a ruby thread in C and call rb_eval_string inside
that,
I can’t find any examples of using the thread functions on google though
so
I’m a bit stuck. Could someone give me a few pointers or perhaps some
example code?

Many thanks
Ian

On 7/13/09, Ian L. [email protected] wrote:

My guess is to spawn a ruby thread in C and call rb_eval_string inside that,
I can’t find any examples of using the thread functions on google though so
I’m a bit stuck. Could someone give me a few pointers or perhaps some
example code?

This is the first time I have ever tried embedding Ruby in C, but I
hope it helps. (The idea is to run ruby from a C thread so the rest
of your C program can maybe run in parallel):

#include <ruby.h>

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

void do_ruby(void param)
{
ruby_init();
rb_eval_string(“loop { puts ‘hello from ruby world’; sleep 5 }”);
ruby_finalize();
}

int main(int argc, char *argv[])
{
pthread_t ruby_thread;

printf(“BEFORE DO_RUBY\n”);

pthread_create( &ruby_thread, NULL, do_ruby, NULL);

printf(“AFTER DO_RUBY\n”);

pthread_join(ruby_thread, NULL);

return 0;
}

gcc -o foo -lpthread -lruby1.8 -I/usr/lib/ruby/1.8/i486-linux foo.c
./foo
BEFORE DO_RUBY
hello from ruby world
AFTER DO_RUBY
hello from ruby world
hello from ruby world
^C(eval): (eval):0:in sleep': (Interrupt) from (eval):0 from (eval):0:in loop’
from (eval):0
(eval): [BUG] Segmentation fault
ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]

Abort

But, be aware:
“ruby is not thread-safe. If you embed ruby into a multi-threaded
application then you will need to semaphore protect all access to
ruby. Warning: Insufficient semaphore protection can be hard
debuggable.” [1]

[1] ruby embedded into c++

Thanks,

I did think of using pthreads, though the code I need to eval will
regularly
touch any number of existing objects so I don’t think there’s a way to
stay
safe using pthreads. Do you know how to spawn a ruby green thread in C?

2009/7/13 [email protected]