summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--NEWS4
-rw-r--r--cont.c16
3 files changed, 27 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index eac30e7087..ac29b59f26 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Thu Nov 10 05:17:25 2011 Koichi Sasada <ko1@atdot.net>
+
+ * cont.c (rb_fiber_m_transfer, rb_fiber_resume): prohibit using
+ "resume" after "transfer" method are used. You should not mix
+ "resume" fiber and "transfer" fiber.
+ [Bug #5526]
+
+ * NEWS: add information about this change.
+
Wed Nov 9 11:40:37 2011 Nobuyoshi Nakada <nobu@ruby-lang.org>
* template/Doxyfile.tmpl (INCLUDE_PATH): add srcdir and include.
diff --git a/NEWS b/NEWS
index b52a7d14a2..b6ddc634f5 100644
--- a/NEWS
+++ b/NEWS
@@ -32,6 +32,10 @@ with all sufficient information, see the ChangeLog file.
* Time#to_s returned encoding defaults to US-ASCII but automatically
transcodes to Encoding.default_internal if it is set.
+ * Fiber
+ * incompatible changes:
+ * Fiber#resume cannot resume a fiber which invokes "Fiber#transfer".
+
* net/imap
* new methods:
* Net::IMAP.default_port
diff --git a/cont.c b/cont.c
index 0ed1f2c032..cb934f79bc 100644
--- a/cont.c
+++ b/cont.c
@@ -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);
}
/*