Skip to content

Commit c414b98

Browse files
committed
Revert "merge revision(s) 62430c1: [Backport #21342]"
This reverts commit 4306c90.
1 parent 22c2262 commit c414b98

File tree

3 files changed

+16
-152
lines changed

3 files changed

+16
-152
lines changed

test/ruby/test_thread.rb

Lines changed: 0 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1557,97 +1557,4 @@ def test_pending_interrupt?
15571557
assert_equal(true, t.pending_interrupt?(Exception))
15581558
assert_equal(false, t.pending_interrupt?(ArgumentError))
15591559
end
1560-
1561-
def test_deadlock_backtrace
1562-
bug21127 = '[ruby-core:120930] [Bug #21127]'
1563-
1564-
expected_stderr = [
1565-
/-:12:in 'Thread#join': No live threads left. Deadlock\? \(fatal\)\n/,
1566-
/2 threads, 2 sleeps current:\w+ main thread:\w+\n/,
1567-
/\* #<Thread:\w+ sleep_forever>\n/,
1568-
:*,
1569-
/^\s*-:6:in 'Object#frame_for_deadlock_test_2'/,
1570-
:*,
1571-
/\* #<Thread:\w+ -:10 sleep_forever>\n/,
1572-
:*,
1573-
/^\s*-:2:in 'Object#frame_for_deadlock_test_1'/,
1574-
:*,
1575-
]
1576-
1577-
assert_in_out_err([], <<-INPUT, [], expected_stderr, bug21127)
1578-
def frame_for_deadlock_test_1
1579-
yield
1580-
end
1581-
1582-
def frame_for_deadlock_test_2
1583-
yield
1584-
end
1585-
1586-
q = Thread::Queue.new
1587-
t = Thread.new { frame_for_deadlock_test_1 { q.pop } }
1588-
1589-
frame_for_deadlock_test_2 { t.join }
1590-
INPUT
1591-
end
1592-
1593-
# [Bug #21342]
1594-
def test_unlock_locked_mutex_with_collected_fiber
1595-
bug21127 = '[ruby-core:120930] [Bug #21127]'
1596-
assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
1597-
begin;
1598-
5.times do
1599-
m = Mutex.new
1600-
Thread.new do
1601-
m.synchronize do
1602-
end
1603-
end.join
1604-
Fiber.new do
1605-
GC.start
1606-
m.lock
1607-
end.resume
1608-
end
1609-
end;
1610-
end
1611-
1612-
def test_unlock_locked_mutex_with_collected_fiber2
1613-
assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
1614-
begin;
1615-
MUTEXES = []
1616-
5.times do
1617-
m = Mutex.new
1618-
Fiber.new do
1619-
GC.start
1620-
m.lock
1621-
end.resume
1622-
MUTEXES << m
1623-
end
1624-
10.times do
1625-
MUTEXES.clear
1626-
GC.start
1627-
end
1628-
end;
1629-
end
1630-
1631-
def test_mutexes_locked_in_fiber_dont_have_aba_issue_with_new_fibers
1632-
assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
1633-
begin;
1634-
mutexes = 1000.times.map do
1635-
Mutex.new
1636-
end
1637-
1638-
mutexes.map do |m|
1639-
Fiber.new do
1640-
m.lock
1641-
end.resume
1642-
end
1643-
1644-
GC.start
1645-
1646-
1000.times.map do
1647-
Fiber.new do
1648-
raise "FAILED!" if mutexes.any?(&:owned?)
1649-
end.resume
1650-
end
1651-
end;
1652-
end
16531560
end

thread.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ rb_threadptr_unlock_all_locking_mutexes(rb_thread_t *th)
445445
th->keeping_mutexes = mutex->next_mutex;
446446

447447
// rb_warn("mutex #<%p> was not unlocked by thread #<%p>", (void *)mutex, (void*)th);
448-
VM_ASSERT(mutex->fiber);
448+
449449
const char *error_message = rb_mutex_unlock_th(mutex, th, mutex->fiber);
450450
if (error_message) rb_bug("invalid keeping_mutexes: %s", error_message);
451451
}

thread_sync.c

Lines changed: 15 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ static VALUE rb_eClosedQueueError;
88
/* Mutex */
99
typedef struct rb_mutex_struct {
1010
rb_fiber_t *fiber;
11-
VALUE thread; // even if the fiber is collected, we might need access to the thread in mutex_free
1211
struct rb_mutex_struct *next_mutex;
1312
struct ccan_list_head waitq; /* protected by GVL */
1413
} rb_mutex_t;
@@ -107,6 +106,8 @@ static const char* rb_mutex_unlock_th(rb_mutex_t *mutex, rb_thread_t *th, rb_fib
107106
*
108107
*/
109108

109+
#define mutex_mark ((void(*)(void*))0)
110+
110111
static size_t
111112
rb_mutex_num_waiting(rb_mutex_t *mutex)
112113
{
@@ -122,39 +123,13 @@ rb_mutex_num_waiting(rb_mutex_t *mutex)
122123

123124
rb_thread_t* rb_fiber_threadptr(const rb_fiber_t *fiber);
124125

125-
static bool
126-
locked_p(rb_mutex_t *mutex)
127-
{
128-
return mutex->fiber != 0;
129-
}
130-
131-
static void
132-
mutex_mark(void *ptr)
133-
{
134-
rb_mutex_t *mutex = ptr;
135-
VALUE fiber;
136-
if (locked_p(mutex)) {
137-
fiber = rb_fiberptr_self(mutex->fiber); // rb_fiber_t* doesn't move along with fiber object
138-
if (fiber) rb_gc_mark_movable(fiber);
139-
rb_gc_mark_movable(mutex->thread);
140-
}
141-
}
142-
143-
static void
144-
mutex_compact(void *ptr)
145-
{
146-
rb_mutex_t *mutex = ptr;
147-
if (locked_p(mutex)) {
148-
mutex->thread = rb_gc_location(mutex->thread);
149-
}
150-
}
151-
152126
static void
153127
mutex_free(void *ptr)
154128
{
155129
rb_mutex_t *mutex = ptr;
156-
if (locked_p(mutex)) {
157-
const char *err = rb_mutex_unlock_th(mutex, rb_thread_ptr(mutex->thread), mutex->fiber);
130+
if (mutex->fiber) {
131+
/* rb_warn("free locked mutex"); */
132+
const char *err = rb_mutex_unlock_th(mutex, rb_fiber_threadptr(mutex->fiber), mutex->fiber);
158133
if (err) rb_bug("%s", err);
159134
}
160135
ruby_xfree(ptr);
@@ -168,7 +143,7 @@ mutex_memsize(const void *ptr)
168143

169144
static const rb_data_type_t mutex_data_type = {
170145
"mutex",
171-
{mutex_mark, mutex_free, mutex_memsize, mutex_compact,},
146+
{mutex_mark, mutex_free, mutex_memsize,},
172147
0, 0, RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY
173148
};
174149

@@ -229,13 +204,12 @@ rb_mutex_locked_p(VALUE self)
229204
{
230205
rb_mutex_t *mutex = mutex_ptr(self);
231206

232-
return RBOOL(locked_p(mutex));
207+
return RBOOL(mutex->fiber);
233208
}
234209

235210
static void
236211
thread_mutex_insert(rb_thread_t *thread, rb_mutex_t *mutex)
237212
{
238-
RUBY_ASSERT(!mutex->next_mutex);
239213
if (thread->keeping_mutexes) {
240214
mutex->next_mutex = thread->keeping_mutexes;
241215
}
@@ -260,24 +234,10 @@ thread_mutex_remove(rb_thread_t *thread, rb_mutex_t *mutex)
260234
}
261235

262236
static void
263-
mutex_set_owner(VALUE self, rb_thread_t *th, rb_fiber_t *fiber)
264-
{
265-
rb_mutex_t *mutex = mutex_ptr(self);
266-
267-
mutex->thread = th->self;
268-
mutex->fiber = fiber;
269-
RB_OBJ_WRITTEN(self, Qundef, th->self);
270-
if (fiber) {
271-
RB_OBJ_WRITTEN(self, Qundef, rb_fiberptr_self(fiber));
272-
}
273-
}
274-
275-
static void
276-
mutex_locked(rb_thread_t *th, rb_fiber_t *fiber, VALUE self)
237+
mutex_locked(rb_thread_t *th, VALUE self)
277238
{
278239
rb_mutex_t *mutex = mutex_ptr(self);
279240

280-
mutex_set_owner(self, th, fiber);
281241
thread_mutex_insert(th, mutex);
282242
}
283243

@@ -298,8 +258,9 @@ rb_mutex_trylock(VALUE self)
298258

299259
rb_fiber_t *fiber = GET_EC()->fiber_ptr;
300260
rb_thread_t *th = GET_THREAD();
261+
mutex->fiber = fiber;
301262

302-
mutex_locked(th, fiber, self);
263+
mutex_locked(th, self);
303264
return Qtrue;
304265
}
305266
else {
@@ -367,7 +328,7 @@ do_mutex_lock(VALUE self, int interruptible_p)
367328
rb_ensure(call_rb_fiber_scheduler_block, self, delete_from_waitq, (VALUE)&sync_waiter);
368329

369330
if (!mutex->fiber) {
370-
mutex_set_owner(self, th, fiber);
331+
mutex->fiber = fiber;
371332
}
372333
}
373334
else {
@@ -397,7 +358,6 @@ do_mutex_lock(VALUE self, int interruptible_p)
397358
rb_ractor_sleeper_threads_inc(th->ractor);
398359
rb_check_deadlock(th->ractor);
399360

400-
RUBY_ASSERT(!th->locking_mutex);
401361
th->locking_mutex = self;
402362

403363
ccan_list_add_tail(&mutex->waitq, &sync_waiter.node);
@@ -408,7 +368,7 @@ do_mutex_lock(VALUE self, int interruptible_p)
408368

409369
// unlocked by another thread while sleeping
410370
if (!mutex->fiber) {
411-
mutex_set_owner(self, th, fiber);
371+
mutex->fiber = fiber;
412372
}
413373

414374
rb_ractor_sleeper_threads_dec(th->ractor);
@@ -422,13 +382,10 @@ do_mutex_lock(VALUE self, int interruptible_p)
422382
if (interruptible_p) {
423383
/* release mutex before checking for interrupts...as interrupt checking
424384
* code might call rb_raise() */
425-
if (mutex->fiber == fiber) {
426-
mutex->thread = Qfalse;
427-
mutex->fiber = NULL;
428-
}
385+
if (mutex->fiber == fiber) mutex->fiber = 0;
429386
RUBY_VM_CHECK_INTS_BLOCKING(th->ec); /* may release mutex */
430387
if (!mutex->fiber) {
431-
mutex_set_owner(self, th, fiber);
388+
mutex->fiber = fiber;
432389
}
433390
}
434391
else {
@@ -447,7 +404,7 @@ do_mutex_lock(VALUE self, int interruptible_p)
447404
}
448405

449406
if (saved_ints) th->ec->interrupt_flag = saved_ints;
450-
if (mutex->fiber == fiber) mutex_locked(th, fiber, self);
407+
if (mutex->fiber == fiber) mutex_locked(th, self);
451408
}
452409

453410
RUBY_DEBUG_LOG("%p locked", mutex);

0 commit comments

Comments
 (0)