Feature #15350 ยป 0001-thread_sync.c-queue_sleep-remove-deadlock-checking.patch
test/ruby/test_thread_queue.rb | ||
---|---|---|
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
|
thread_sync.c | ||
---|---|---|
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 {
|
||
... | ... | |
} 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)
|
||
{
|
||
... | ... | |
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);
|
||
}
|
||
}
|
||
... | ... | |
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);
|
||
}
|
||
}
|
||
-
|