From 776af67b282cea12f9256f566ab7d5543a40b453 Mon Sep 17 00:00:00 2001 From: matz Date: Fri, 28 Nov 2008 15:23:09 +0000 Subject: [PATCH] * cont.c (fiber_alloc): separate allocation and initialization. allow subclass to override #initialize. [ruby-core:20086] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@20388 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 5 +++++ cont.c | 45 +++++++++++++++++++++++++++------------------ 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index de89039f1c..3976cd804c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Sat Nov 29 00:18:30 2008 Yukihiro Matsumoto + + * cont.c (fiber_alloc): separate allocation and initialization. + allow subclass to override #initialize. [ruby-core:20086] + Fri Nov 28 18:31:21 2008 Yukihiro Matsumoto * ext/socket/socket.c (sock_s_getaddrinfo): refactored to remove diff --git a/cont.c b/cont.c index e91438a393..515e819fb1 100644 --- a/cont.c +++ b/cont.c @@ -64,8 +64,10 @@ static VALUE rb_eFiberError; #define GetContPtr(obj, ptr) \ Data_Get_Struct(obj, rb_context_t, ptr) -#define GetFiberPtr(obj, ptr) \ - Data_Get_Struct(obj, rb_fiber_t, ptr) +#define GetFiberPtr(obj, ptr) do {\ + ptr = (rb_fiber_t*)DATA_PTR(obj);\ + if (!ptr) rb_raise(rb_eFiberError, "uninitialized fiber");\ +} while(0) NOINLINE(static VALUE cont_capture(volatile int *stat)); @@ -568,26 +570,33 @@ rb_cont_call(int argc, VALUE *argv, VALUE contval) #define FIBER_VM_STACK_SIZE (4 * 1024) -static rb_fiber_t * +static VALUE fiber_alloc(VALUE klass) { - rb_fiber_t *fib; - volatile VALUE fibval = Data_Make_Struct(klass, rb_fiber_t, fiber_mark, fiber_free, fib); + return Data_Wrap_Struct(klass, fiber_mark, fiber_free, 0); +} +static rb_fiber_t* +fiber_t_alloc(VALUE fibval) +{ + rb_fiber_t *fib = ALLOC(rb_fiber_t); + + memset(fib, 0, sizeof(rb_fiber_t)); fib->cont.self = fibval; fib->cont.type = FIBER_CONTEXT; cont_init(&fib->cont); fib->prev = Qnil; fib->status = CREATED; + DATA_PTR(fibval) = fib; + return fib; } static VALUE -fiber_new(VALUE klass, VALUE proc) +fiber_init(VALUE fibval, VALUE proc) { - rb_fiber_t *fib = fiber_alloc(klass); - VALUE fibval = fib->cont.self; + rb_fiber_t *fib = fiber_t_alloc(fibval); rb_context_t *cont = &fib->cont; rb_thread_t *th = &cont->saved_thread; @@ -623,16 +632,16 @@ fiber_new(VALUE klass, VALUE proc) return fibval; } +static VALUE +rb_fiber_init(VALUE fibval) +{ + return fiber_init(fibval, rb_block_proc()); +} + VALUE rb_fiber_new(VALUE (*func)(ANYARGS), VALUE obj) { - return fiber_new(rb_cFiber, rb_proc_new(func, obj)); -} - -static VALUE -rb_fiber_s_new(VALUE self) -{ - return fiber_new(self, rb_block_proc()); + return fiber_init(fiber_alloc(rb_cFiber), rb_proc_new(func, obj)); } static VALUE @@ -717,7 +726,7 @@ root_fiber_alloc(rb_thread_t *th) rb_fiber_t *fib; /* no need to allocate vm stack */ - fib = fiber_alloc(rb_cFiber); + fib = fiber_t_alloc(fiber_alloc(rb_cFiber)); fib->cont.type = ROOT_FIBER_CONTEXT; fib->prev_fiber = fib->next_fiber = fib; @@ -862,10 +871,10 @@ void Init_Cont(void) { rb_cFiber = rb_define_class("Fiber", rb_cObject); - rb_undef_alloc_func(rb_cFiber); + rb_define_alloc_func(rb_cFiber, fiber_alloc); rb_eFiberError = rb_define_class("FiberError", rb_eStandardError); - rb_define_singleton_method(rb_cFiber, "new", rb_fiber_s_new, 0); rb_define_singleton_method(rb_cFiber, "yield", rb_fiber_s_yield, -1); + rb_define_method(rb_cFiber, "initialize", rb_fiber_init, 0); rb_define_method(rb_cFiber, "resume", rb_fiber_m_resume, -1); }