summaryrefslogtreecommitdiff
path: root/cont.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-04-03 10:21:47 (GMT)
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-04-03 10:21:47 (GMT)
commitdb3cc675f3c4e832028b67a202991fa78aa0a694 (patch)
tree032ecc9ad5bf24c2353fd1548743415d7178c0bd /cont.c
parentc3da1625962acf32a47a4e12929fa9d45be9693e (diff)
Fix Fiber with Thread issue on Windows [Bug #14642]
* cont.c (rb_threadptr_root_fiber_setup): divide into two functions: * rb_threadptr_root_fiber_setup_by_parent(): called by the parent thread. * rb_threadptr_root_fiber_setup_by_child(): called by the created thread. `rb_threadptr_root_fiber_setup()` is called by the parent thread and set fib->fib_handle by ConvertThreadToFiber() on the parent thread on Windows enveironment. This means that root_fib->fib_handle of child thread is initialized with parent thread's Fiber handle. Furthermore, second call of `ConvertThreadToFiber()` for the same thread fails. This patch solves this weird situateion. However, maybe we can make more clean code. * thread.c (thread_start_func_2): call `rb_threadptr_root_fiber_setup_by_child()` at thread initialize routine. * vm.c (th_init): call `rb_threadptr_root_fiber_setup_by_parent()`. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63073 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'cont.c')
-rw-r--r--cont.c28
1 files changed, 25 insertions, 3 deletions
diff --git a/cont.c b/cont.c
index 9cb0d96..253a056 100644
--- a/cont.c
+++ b/cont.c
@@ -1464,6 +1464,18 @@ rb_fiber_start(void)
VM_UNREACHABLE(rb_fiber_start);
}
+#ifdef _WIN32
+static HANDLE
+win32_convert_thread_to_fiber(void)
+{
+ HANDLE fib_handle = ConvertThreadToFiber(0);
+ if (!fib_handle) {
+ rb_bug("rb_threadptr_root_fiber_setup_by_child: ConvertThreadToFiber() failed - %s\n", rb_w32_strerror(-1));
+ }
+ return fib_handle;
+}
+#endif
+
static rb_fiber_t *
root_fiber_alloc(rb_thread_t *th)
{
@@ -1480,7 +1492,7 @@ root_fiber_alloc(rb_thread_t *th)
#if FIBER_USE_NATIVE
#ifdef _WIN32
if (fib->fib_handle == 0) {
- fib->fib_handle = ConvertThreadToFiber(0);
+ fib->fib_handle = win32_convert_thread_to_fiber();
}
#endif
#endif
@@ -1488,7 +1500,7 @@ root_fiber_alloc(rb_thread_t *th)
}
void
-rb_threadptr_root_fiber_setup(rb_thread_t *th)
+rb_threadptr_root_fiber_setup_by_parent(rb_thread_t *th)
{
rb_fiber_t *fib = ruby_mimmalloc(sizeof(rb_fiber_t));
MEMZERO(fib, rb_fiber_t, 1);
@@ -1497,10 +1509,20 @@ rb_threadptr_root_fiber_setup(rb_thread_t *th)
fib->cont.saved_ec.thread_ptr = th;
fiber_status_set(fib, FIBER_RESUMED); /* skip CREATED */
th->ec = &fib->cont.saved_ec;
+}
+
+void
+rb_threadptr_root_fiber_setup_by_child(rb_thread_t *th)
+{
#if FIBER_USE_NATIVE
#ifdef _WIN32
+ rb_fiber_t *fib = th->ec->fiber_ptr;
+
if (fib->fib_handle == 0) {
- fib->fib_handle = ConvertThreadToFiber(0);
+ fib->fib_handle = win32_convert_thread_to_fiber();
+ }
+ else {
+ rb_bug("rb_threadptr_root_fiber_setup_by_child: fib_handle is not NULL.");
}
#endif
#endif