diff options
author | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-04-03 10:21:47 +0000 |
---|---|---|
committer | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-04-03 10:21:47 +0000 |
commit | db3cc675f3c4e832028b67a202991fa78aa0a694 (patch) | |
tree | 032ecc9ad5bf24c2353fd1548743415d7178c0bd /cont.c | |
parent | c3da1625962acf32a47a4e12929fa9d45be9693e (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.c | 28 |
1 files changed, 25 insertions, 3 deletions
@@ -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 |