将Ruby的事件循环集成到C扩展中

时间:2013-06-02 14:55:07

标签: c ruby linux ipc

我想知道如何将Ruby的事件循环与C中的Ruby扩展集成。我不确定这是否是我正在尝试做的正确方法,所以我将解释这个问题。

我正在使用msgrcvmsgsnd(IPC),因此在Ruby C扩展和另一个应用程序之间发送消息。问题是接收消息的扩展方法会创建一个无限循环:

do{
    if(msgrcv(msqid, &rcvbuffer, MAXSIZE, 1, 0) < 0){
        printf("Error");
    }else{
        rb_funcall(self, rb_intern("callback_method"), 1, rb_str_new2(rcvbuffer.mtext));
    }
} while(strcmp(rcvbuffer.mtext, "exit") != 0);

并锁定了ruby的解释器。我希望能够在没有阻塞的情况下在Ruby扩展中调用receiver方法。

如何做到这一点?

1 个答案:

答案 0 :(得分:2)

未经测试,这假设你想在没有消息时调用类上的某个方法(显然你需要实现):

do{
    if( msgrcv( msqid, &rcvbuffer, MAXSIZE, 1, IPC_NOWAIT ) < 0) {
        // Handle error conditions
        if ( rcvbuffer.errno == ENOMSG ) {
          rb_funcall(self, rb_intern("no_msg_callback_method"), 0);
          // Or you could simply  . . .
          // break;
        } else {
          printf("Error");
        }
    }else{
        rb_funcall(self, rb_intern("callback_method"), 1, rb_str_new2(rcvbuffer.mtext));
    }
} while(strcmp(rcvbuffer.mtext, "exit") != 0);

您的另一个选择是设置一个标志,并在没有消息时允许循环退出。然后方法调用者需要确定它是否收到了“退出”消息(也发送到callback_method),或者当前没有要处理的消息,所以可以做其他事情。