mirror of
https://github.com/ruby/ruby.git
synced 2025-09-15 16:44:01 +02:00
merge revision(s) eacedcfe44
: [Backport #19105]
mutex: Raise a ThreadError when detecting a fiber deadlock (#6680) [Bug #19105] If no fiber scheduler is registered and the fiber that owns the lock and the one that try to acquire it both belong to the same thread, we're in a deadlock case. Co-authored-by: Jean Boussier <byroot@ruby-lang.org> --- test/fiber/test_mutex.rb | 22 +++++++++++++++++++++- thread_sync.c | 4 ++++ 2 files changed, 25 insertions(+), 1 deletion(-)
This commit is contained in:
parent
db1aa39ffc
commit
6181839531
3 changed files with 26 additions and 2 deletions
|
@ -194,7 +194,7 @@ class TestFiberMutex < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_mutex_deadlock
|
def test_mutex_deadlock
|
||||||
error_pattern = /No live threads left. Deadlock\?/
|
error_pattern = /lock already owned by another fiber/
|
||||||
|
|
||||||
assert_in_out_err %W[-I#{__dir__} -], <<-RUBY, ['in synchronize'], error_pattern, success: false
|
assert_in_out_err %W[-I#{__dir__} -], <<-RUBY, ['in synchronize'], error_pattern, success: false
|
||||||
require 'scheduler'
|
require 'scheduler'
|
||||||
|
@ -217,4 +217,24 @@ class TestFiberMutex < Test::Unit::TestCase
|
||||||
thread.join
|
thread.join
|
||||||
RUBY
|
RUBY
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_mutex_fiber_deadlock_no_scheduler
|
||||||
|
thr = Thread.new do
|
||||||
|
loop do
|
||||||
|
sleep 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
mutex = Mutex.new
|
||||||
|
mutex.synchronize do
|
||||||
|
error = assert_raise ThreadError do
|
||||||
|
Fiber.new do
|
||||||
|
mutex.lock
|
||||||
|
end.resume
|
||||||
|
end
|
||||||
|
assert_includes error.message, "deadlock; lock already owned by another fiber belonging to the same thread"
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
thr&.kill&.join
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -311,6 +311,10 @@ do_mutex_lock(VALUE self, int interruptible_p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if (!th->vm->thread_ignore_deadlock && rb_fiber_threadptr(mutex->fiber) == th) {
|
||||||
|
rb_raise(rb_eThreadError, "deadlock; lock already owned by another fiber belonging to the same thread");
|
||||||
|
}
|
||||||
|
|
||||||
enum rb_thread_status prev_status = th->status;
|
enum rb_thread_status prev_status = th->status;
|
||||||
rb_hrtime_t *timeout = 0;
|
rb_hrtime_t *timeout = 0;
|
||||||
rb_hrtime_t rel = rb_msec2hrtime(100);
|
rb_hrtime_t rel = rb_msec2hrtime(100);
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
|
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
|
||||||
#define RUBY_VERSION_TEENY 3
|
#define RUBY_VERSION_TEENY 3
|
||||||
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
|
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
|
||||||
#define RUBY_PATCHLEVEL 178
|
#define RUBY_PATCHLEVEL 179
|
||||||
|
|
||||||
#define RUBY_RELEASE_YEAR 2022
|
#define RUBY_RELEASE_YEAR 2022
|
||||||
#define RUBY_RELEASE_MONTH 11
|
#define RUBY_RELEASE_MONTH 11
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue