Subject: Re: [ruby-ffi] SystemStackError of callback |
From: Wayne Meissner |
Date: 7/2/10 1:05 AM |
To: ruby-ffi@googlegroups.com |
There are a few problems in your code. 1) Using a block as an async callback won't work, and could potentially crash the VM. You need to instantiate it as a Proc or Function and keep a strong ref to that object. e.g. cb = Proc.new do|a, b|
100.times do|d|
puts a, b.read_int end end async_call(cb, 1, p) 2) Your native function passes a pointer to data on its stack to the newly created thread. This is a really bad thing, since the new thread might start running after the native function has returned, and that stack space has been re-used for some other data. You could use malloc in async_call(), and free in call() to manage that data. 3) Make sure you're using the latest FFI code from github with ruby-1.9, or JRuby. Callbacks from non-ruby threads were not properly supported in earlier versions (up to and including 0.6.3). JRuby has always been fine though. Ruby 1.8 won't work at all with callbacks from non-ruby threads, and could result in undefined behaviour and/or crashes. On 2 July 2010 00:40, tlayboy <tlayboy@gmail.com> wrote:
Hi all, I am in troble with SystemStackError of callback. Does anyone know why this error is occured? My code is like this. ############################ C library ############################ typedef void (*callback)(int, void *); pthread_t thread; struct cb_info info; struct cb_info { callback cb; int data; void *p; }; void *call(void *data) { struct cb_info *info = (struct cb_info *)data; info->cb(info->data, info->p); } void async_call(callback cb, unsigned int data, void *p) { int ret; info.cb = rcb; info.data = data; info.p = p; if ((ret = pthread_create(&thread, NULL, call, (void *)&info)) != 0) { perror("ptherad_create"); exit(EXIT_FAILURE); } } ############################ Ruby Code ############################ p = FFI::MemoryPointer.new(:int) p.write_int(2) async_call(1, p) do|a, b|
100.times do|d|
puts a, b.read_int end end ############################ Output ############################ 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 /usr/lib/ruby/1.8/pp.rb:133:in `pp': stack level too deep (SystemStackError) from /usr/lib/ruby/1.8/pp.rb:77:in `pp' from /usr/lib/ruby/1.8/pp.rb:119:in `guard_inspect_key' from /usr/lib/ruby/1.8/pp.rb:77:in `pp' from /usr/lib/ruby/1.8/pp.rb:60:in `pp' from /usr/lib/ruby/1.8/pp.rb:59:in `each' from /usr/lib/ruby/1.8/pp.rb:59:in `pp' from libcb.rb:35 from (eval):6:in `call' from (eval):6:in `async_call' from libcb.rb:34 from libcb.rb:33:in `times' from libcb.rb:33 thank you,