diff options
Diffstat (limited to 'cont.c')
-rw-r--r-- | cont.c | 16 |
1 files changed, 14 insertions, 2 deletions
@@ -103,6 +103,12 @@ typedef struct rb_fiber_struct { enum fiber_status status; struct rb_fiber_struct *prev_fiber; struct rb_fiber_struct *next_fiber; + /* If a fiber invokes "transfer", + * then this fiber can't "resume" any more after that. + * You shouldn't mix "transfer" and "resume". + */ + int transfered; + #if FIBER_USE_NATIVE #ifdef _WIN32 void *fib_handle; @@ -1322,6 +1328,9 @@ rb_fiber_resume(VALUE fibval, int argc, VALUE *argv) if (fib->prev != Qnil || fib->cont.type == ROOT_FIBER_CONTEXT) { rb_raise(rb_eFiberError, "double resume"); } + if (fib->transfered != 0) { + rb_raise(rb_eFiberError, "cannot resume transferred Fiber"); + } return fiber_switch(fibval, argc, argv, 1); } @@ -1389,9 +1398,12 @@ rb_fiber_m_resume(int argc, VALUE *argv, VALUE fib) * back to this fiber before it can yield and resume. */ static VALUE -rb_fiber_m_transfer(int argc, VALUE *argv, VALUE fib) +rb_fiber_m_transfer(int argc, VALUE *argv, VALUE fibval) { - return rb_fiber_transfer(fib, argc, argv); + rb_fiber_t *fib; + GetFiberPtr(fibval, fib); + fib->transfered = 1; + return rb_fiber_transfer(fibval, argc, argv); } /* |