From afd2b61583a567be4db1831a9a1a6cd32db06833 Mon Sep 17 00:00:00 2001
From: Eric Wong <e@80x24.org>
Date: Tue, 27 Nov 2018 22:49:10 +0000
Subject: [PATCH] thread_sync.c (queue_sleep): remove deadlock checking

Queue may be used inside signal handlers nowadays, so deadlock
checking is unnecessary and prevents single-threaded use.

We don't have deadlock checking for reading pipes/socket or
File#flock, either.
---
 test/ruby/test_thread_queue.rb | 10 ++++++++++
 thread_sync.c                  | 21 ++++++++++++---------
 2 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/test/ruby/test_thread_queue.rb b/test/ruby/test_thread_queue.rb
index 8cebbbecb4..929924f7e4 100644
--- a/test/ruby/test_thread_queue.rb
+++ b/test/ruby/test_thread_queue.rb
@@ -567,6 +567,16 @@ def test_queue_with_trap
       puts q.pop
       puts 'exit'
     INPUT
+
+    skip 'fork not present' unless Process.respond_to?(:fork)
+    assert_separately([], <<-INPUT)
+      q = Queue.new
+      trap(:CHLD) { q.push :CHLD }
+      pid = fork { exit!(0) }
+      q.pop
+      pid, st = Process.waitpid2(pid)
+      assert_predicate st, :success?
+    INPUT
   end
 
   def test_fork_while_queue_waiting
diff --git a/thread_sync.c b/thread_sync.c
index b79db1fee3..b79514e925 100644
--- a/thread_sync.c
+++ b/thread_sync.c
@@ -862,13 +862,6 @@ rb_queue_push(VALUE self, VALUE obj)
     return queue_do_push(self, queue_ptr(self), obj);
 }
 
-static VALUE
-queue_sleep(VALUE arg)
-{
-    rb_thread_sleep_deadly_allow_spurious_wakeup();
-    return Qnil;
-}
-
 struct queue_waiter {
     struct sync_waiter w;
     union {
@@ -877,6 +870,16 @@ struct queue_waiter {
     } as;
 };
 
+static VALUE
+queue_sleep(VALUE p)
+{
+    struct queue_waiter *qw = (struct queue_waiter *)p;
+
+    sleep_forever(qw->w.th, 0);
+
+    return Qnil;
+}
+
 static VALUE
 queue_sleep_done(VALUE p)
 {
@@ -922,7 +925,7 @@ queue_do_pop(VALUE self, struct rb_queue *q, int should_block)
 	    list_add_tail(&qw.as.q->waitq, &qw.w.node);
 	    qw.as.q->num_waiting++;
 
-	    rb_ensure(queue_sleep, self, queue_sleep_done, (VALUE)&qw);
+	    rb_ensure(queue_sleep, (VALUE)&qw, queue_sleep_done, (VALUE)&qw);
 	}
     }
 
@@ -1162,7 +1165,7 @@ rb_szqueue_push(int argc, VALUE *argv, VALUE self)
 	    list_add_tail(pushq, &qw.w.node);
 	    sq->num_waiting_push++;
 
-	    rb_ensure(queue_sleep, self, szqueue_sleep_done, (VALUE)&qw);
+	    rb_ensure(queue_sleep, (VALUE)&qw, szqueue_sleep_done, (VALUE)&qw);
 	}
     }
 
-- 
EW

