mirror of
https://github.com/ruby/ruby.git
synced 2026-01-27 04:24:23 +00:00
thread.c (blocking_region_end): clear ubf before unregister_ubf_list
If we keep ubf set after unregistering, there is a window for other threads (including timer thread) to put this thread back on the ubf_list right away. Entering ubf_list unexpectedly after GVL acquisition may cause spurious wakeup and trigger unexpected behavior. Finally, clear ubf before acquiring GVL, to since ubf is useless during GVL acquisition anyways and we don't want to waste cycles in other threads calling ubf for useless work. [ruby-core:88141] [Bug #14945] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64083 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
297ae3437e
commit
856bd77aea
7
thread.c
7
thread.c
@ -1397,12 +1397,15 @@ blocking_region_begin(rb_thread_t *th, struct rb_blocking_region_buffer *region,
|
||||
static inline void
|
||||
blocking_region_end(rb_thread_t *th, struct rb_blocking_region_buffer *region)
|
||||
{
|
||||
/* entry to ubf_list still permitted at this point, make it impossible: */
|
||||
unblock_function_clear(th);
|
||||
/* entry to ubf_list impossible at this point, so unregister is safe: */
|
||||
unregister_ubf_list(th);
|
||||
|
||||
gvl_acquire(th->vm, th);
|
||||
rb_thread_set_current(th);
|
||||
thread_debug("leave blocking region (%p)\n", (void *)th);
|
||||
unregister_ubf_list(th);
|
||||
th->blocking_region_buffer = 0;
|
||||
unblock_function_clear(th);
|
||||
if (th->status == THREAD_STOPPED) {
|
||||
th->status = region->prev_status;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user