1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

thread.c: fix overly long Thread#join w/ timeout

* test/ruby/test_thread.rb (test_signal_at_join): test with timeout
* thread.c (sleep_wait_for_interrupt): remove
  (thread_join_sleep): use native_sleep directly to avoid extra
  missing thread status change
  [Bug #14181]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61302 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
normal 2017-12-17 08:26:17 +00:00
parent 78cc1491d5
commit db9523ef47
2 changed files with 21 additions and 10 deletions

View file

@ -1284,6 +1284,20 @@ q.pop
end
end
end
n.times do
w = Thread.start { sleep 30 }
begin
f.puts
f.gets
ensure
w.kill
t0 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
w.join(30)
t1 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
diff = t1 - t0
assert_operator diff, :<=, 2
end
end
end
};
end

View file

@ -91,7 +91,6 @@ static VALUE sym_never;
static ID id_locals;
static void sleep_timeval(rb_thread_t *th, struct timeval time, int spurious_check);
static void sleep_wait_for_interrupt(rb_thread_t *th, double sleepsec, int spurious_check);
static void sleep_forever(rb_thread_t *th, int nodeadlock, int spurious_check);
static void rb_thread_sleep_deadly_allow_spurious_wakeup(void);
static double timeofday(void);
@ -888,18 +887,22 @@ thread_join_sleep(VALUE arg)
rb_check_deadlock(th->vm);
native_sleep(th, 0);
th->vm->sleeper--;
RUBY_VM_CHECK_INTS_BLOCKING(th->ec);
th->status = THREAD_RUNNABLE;
}
else {
double now = timeofday();
struct timeval tv;
if (now > limit) {
thread_debug("thread_join: timeout (thid: %"PRI_THREAD_ID")\n",
thread_id_str(target_th));
return Qfalse;
}
sleep_wait_for_interrupt(th, limit - now, 0);
tv = double2timeval(limit - now);
th->status = THREAD_STOPPED;
native_sleep(th, &tv);
}
RUBY_VM_CHECK_INTS_BLOCKING(th->ec);
th->status = THREAD_RUNNABLE;
thread_debug("thread_join: interrupted (thid: %"PRI_THREAD_ID", status: %s)\n",
thread_id_str(target_th), thread_status_name(target_th, TRUE));
}
@ -1231,12 +1234,6 @@ timeofday(void)
}
}
static void
sleep_wait_for_interrupt(rb_thread_t *th, double sleepsec, int spurious_check)
{
sleep_timeval(th, double2timeval(sleepsec), spurious_check);
}
void
rb_thread_wait_for(struct timeval time)
{