summaryrefslogtreecommitdiff
path: root/cont.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-11-28 15:23:09 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-11-28 15:23:09 +0000
commit776af67b282cea12f9256f566ab7d5543a40b453 (patch)
treee9352c455968815820cfd7fe5975c194735aaa47 /cont.c
parent46e431e3eb410a6168cd885ac0a327a4b74c9fde (diff)
* 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
Diffstat (limited to 'cont.c')
-rw-r--r--cont.c43
1 files changed, 26 insertions, 17 deletions
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;
}
-VALUE
-rb_fiber_new(VALUE (*func)(ANYARGS), VALUE obj)
+static VALUE
+rb_fiber_init(VALUE fibval)
{
- return fiber_new(rb_cFiber, rb_proc_new(func, obj));
+ return fiber_init(fibval, rb_block_proc());
}
-static VALUE
-rb_fiber_s_new(VALUE self)
+VALUE
+rb_fiber_new(VALUE (*func)(ANYARGS), VALUE obj)
{
- 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);
}