mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
thread_sync.c (rb_mutex_sleep): skip interrupt check before sleep
We do not want to risk switching threads before going to sleep because it can cause unexpected wakeups and put us in an unexpected state when used with ConditionVariable. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64464 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
17d20383ef
commit
2e420b8b99
2 changed files with 11 additions and 5 deletions
7
thread.c
7
thread.c
|
@ -94,7 +94,8 @@ static ID id_locals;
|
|||
|
||||
enum SLEEP_FLAGS {
|
||||
SLEEP_DEADLOCKABLE = 0x1,
|
||||
SLEEP_SPURIOUS_CHECK = 0x2
|
||||
SLEEP_SPURIOUS_CHECK = 0x2,
|
||||
SLEEP_BEFORE_CHECK_INTS = 0x4
|
||||
};
|
||||
|
||||
static void sleep_timespec(rb_thread_t *, struct timespec, unsigned int fl);
|
||||
|
@ -1187,7 +1188,9 @@ sleep_forever(rb_thread_t *th, unsigned int fl)
|
|||
|
||||
status = fl & SLEEP_DEADLOCKABLE ? THREAD_STOPPED_FOREVER : THREAD_STOPPED;
|
||||
th->status = status;
|
||||
if (!(fl & SLEEP_BEFORE_CHECK_INTS)) {
|
||||
RUBY_VM_CHECK_INTS_BLOCKING(th->ec);
|
||||
}
|
||||
while (th->status == status) {
|
||||
if (fl & SLEEP_DEADLOCKABLE) {
|
||||
th->vm->sleeper++;
|
||||
|
@ -1293,7 +1296,9 @@ sleep_timespec(rb_thread_t *th, struct timespec ts, unsigned int fl)
|
|||
getclockofday(&end);
|
||||
timespec_add(&end, &ts);
|
||||
th->status = THREAD_STOPPED;
|
||||
if (!(fl & SLEEP_BEFORE_CHECK_INTS)) {
|
||||
RUBY_VM_CHECK_INTS_BLOCKING(th->ec);
|
||||
}
|
||||
while (th->status == THREAD_STOPPED) {
|
||||
native_sleep(th, &ts);
|
||||
woke = vm_check_ints_blocking(th->ec);
|
||||
|
|
|
@ -438,7 +438,7 @@ rb_mutex_cleanup_keeping_mutexes(const rb_thread_t *current_thread)
|
|||
static VALUE
|
||||
rb_mutex_sleep_forever(VALUE time)
|
||||
{
|
||||
rb_thread_sleep_deadly_allow_spurious_wakeup();
|
||||
sleep_forever(GET_THREAD(), SLEEP_DEADLOCKABLE|SLEEP_BEFORE_CHECK_INTS);
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
|
@ -446,7 +446,8 @@ static VALUE
|
|||
rb_mutex_wait_for(VALUE time)
|
||||
{
|
||||
struct timespec *t = (struct timespec*)time;
|
||||
sleep_timespec(GET_THREAD(), *t, 0); /* permit spurious check */
|
||||
/* permit spurious check */
|
||||
sleep_timespec(GET_THREAD(), *t, SLEEP_BEFORE_CHECK_INTS);
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue