void* cfunc_rubyvm_open(void *args) { struct cfunc_rubyvm_data *data = args; mrb_state *mrb = mrb_open(); data->state = mrb; #ifdef DISABLE_GEMS init_cfunc_module(mrb); #endif int n = mrb_read_irep(mrb, data->mrb_data); mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb)); if (mrb->exc) { return NULL; } while(true) { pthread_mutex_lock(&data->queue_mutex); while(data->queue->length == 0) { pthread_cond_wait(&data->queue_cond, &data->queue_mutex); } struct queue_task *task = vector_dequeue(data->queue); task->status = queue_task_running; mrb_sym taskname = mrb_intern(mrb, task->name); int args_len = task->args_len; mrb_value *args = mrb_malloc(mrb, sizeof(struct task_arg) * task->args_len); int i; for(i=0; i<task->args_len; ++i) { args[i] = task_arg_to_mrb_value(data->state, task->args[i]); } pthread_mutex_unlock(&data->queue_mutex); mrb_value result = mrb_funcall_argv(mrb, mrb_top_self(data->state), taskname, args_len, args); task->result = mrb_value_to_task_arg(mrb, result); task->status = queue_task_finished; pthread_cond_signal(&task->sync_cond); mrb_free(mrb, args); free_queue_task(mrb, task); } return NULL; }
static void cfunc_rubyvm_task_data_destructor(mrb_state *mrb, void *p) { free_queue_task((struct queue_task*)p); };