コード例 #1
0
ファイル: thread.c プロジェクト: alloy/mr-experimental
static VALUE
thread_initialize(VALUE thread, SEL sel, int argc, const VALUE *argv)
{
    if (!rb_block_given_p()) {
	rb_raise(rb_eThreadError, "must be called with a block");
    }
    rb_vm_block_t *b = rb_vm_current_block();
    assert(b != NULL);

    rb_vm_thread_t *t = GetThreadPtr(thread);
    rb_vm_thread_pre_init(t, b, argc, argv, rb_vm_create_vm());

    // The thread's group is always the parent's one.
    rb_thgroup_add(GetThreadPtr(rb_vm_current_thread())->group, thread);

    // Retain the Thread object to avoid a potential GC, the corresponding
    // release is done in rb_vm_thread_run().
    rb_objc_retain((void *)thread);

    if (pthread_create(&t->thread, NULL, (void *(*)(void *))rb_vm_thread_run,
		(void *)thread) != 0) {
	rb_sys_fail("pthread_create() failed");
    }

    return thread;
}
コード例 #2
0
ファイル: thread.c プロジェクト: 1nueve/MacRuby
static VALUE
thread_initialize(VALUE thread, SEL sel, int argc, const VALUE *argv)
{
    if (!rb_block_given_p()) {
	rb_raise(rb_eThreadError, "must be called with a block");
    }
    rb_vm_block_t *b = rb_vm_current_block();
    assert(b != NULL);

    rb_vm_thread_t *t = GetThreadPtr(thread);
    if (t->thread != 0) {
	rb_raise(rb_eThreadError, "already initialized thread");
    }
    rb_vm_thread_pre_init(t, b, argc, argv, rb_vm_create_vm());

    // The thread's group is always the parent's one.
    // The parent group might be nil (ex. if created from GCD).
    VALUE group = GetThreadPtr(rb_vm_current_thread())->group;
    if (group != Qnil) {
	thgroup_add_m(group, thread, false);
    }

    // Retain the Thread object to avoid a potential GC, the corresponding
    // release is done in rb_vm_thread_run().
    GC_RETAIN(thread);

    // Prepare attributes for the thread.
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
    pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

    // Register the thread to the core. We are doing this before actually
    // running it because the current thread might perform a method poking at
    // the current registered threads (such as Kernel#sleep) right after that.
    rb_vm_register_thread(thread);

    // Launch it.
    if (pthread_create(&t->thread, &attr, (void *(*)(void *))rb_vm_thread_run,
		(void *)thread) != 0) {
	rb_sys_fail("pthread_create() failed");
    }
    pthread_attr_destroy(&attr);

    return thread;
}