【发布时间】:2018-09-26 21:00:33
【问题描述】:
目标:允许 c 扩展接收块/过程以延迟执行,同时保留当前执行上下文。
我有一个接受callback(通过VALUE hash 参数)或block 的c 方法(暴露于ruby)。
// For brevity, lets assume m_CBYO is setup to make a CBYO module available to ruby
extern VALUE m_CBYO;
VALUE CBYO_add_callback(VALUE callback)
{
if (rb_block_given_p()) {
callback = rb_block_proc();
}
if (NIL_P(callback)) {
rb_raise(rb_eArgError, "either a block or callback proc is required");
}
// method is called here to add the callback proc to rb_callbacks
}
rb_define_module_function(m_CBYO, "add_callback", CBYO_add_callback, 1);
我有一个结构用来存储这些数据和一些额外的数据:
struct rb_callback
{
VALUE rb_cb;
unsigned long long lastcall;
struct rb_callback *next;
};
static struct rb_callback *rb_callbacks = NULL;
到时候(由 epoll 触发),我遍历回调并执行每个回调:
rb_funcall(cb->rb_cb, rb_intern("call"), 0);
当这种情况发生时,我看到它成功地执行了回调中的 ruby 代码,但是,它正在转义当前的执行上下文。
例子:
# From ruby including the above extension
CBYO.add_callback do
puts "Hey now."
end
loop do
puts "Waiting for signal..."
sleep 1
end
当收到信号时(通过 epoll),我将看到以下内容:
$> Waiting for signal...
$> Waiting for signal...
$> Hey now.
$> // process hangs
$> // Another signal occurs
$> [BUG] vm_call_cfunc - cfp consistency error
有时,在错误再次出现之前,我可以处理多个信号。
【问题讨论】:
标签: c ruby ruby-c-extension