Improve handling of urgent notification pipe.

This commit is contained in:
Samuel Williams 2020-09-06 14:48:52 +12:00
parent 3dc0fc11f0
commit 1a0cfe2839
Notes: git 2020-09-14 13:44:36 +09:00
2 changed files with 58 additions and 64 deletions

View File

@ -15,11 +15,9 @@ class Scheduler
@writable = {} @writable = {}
@waiting = {} @waiting = {}
@urgent = nil
@lock = Mutex.new @lock = Mutex.new
@locking = 0 @locking = 0
@ready = [] @ready = Array.new
end end
attr :readable attr :readable
@ -51,11 +49,17 @@ class Scheduler
# puts "writable: #{writable}" if writable&.any? # puts "writable: #{writable}" if writable&.any?
readable&.each do |io| readable&.each do |io|
@readable[io]&.resume if fiber = @readable.delete(io)
fiber.resume
elsif io == @urgent.first
@urgent.first.read_nonblock(1024)
end
end end
writable&.each do |io| writable&.each do |io|
@writable[io]&.resume if fiber = @writable.delete(io)
fiber.resume
end
end end
if @waiting.any? if @waiting.any?
@ -73,9 +77,6 @@ class Scheduler
end end
if @ready.any? if @ready.any?
# Clear out the urgent notification pipe.
@urgent.first.read_nonblock(1024)
ready = nil ready = nil
@lock.synchronize do @lock.synchronize do
@ -114,9 +115,6 @@ class Scheduler
Fiber.yield Fiber.yield
@readable.delete(io)
@writable.delete(io)
return true return true
end end
@ -130,10 +128,10 @@ class Scheduler
def mutex_unlock(mutex, fiber) def mutex_unlock(mutex, fiber)
@lock.synchronize do @lock.synchronize do
@ready << fiber @ready << fiber
if @urgent
@urgent.last.write('.')
end end
if io = @urgent&.last
@urgent.last.write_nonblock('.')
end end
end end

View File

@ -268,8 +268,8 @@ do_mutex_lock(VALUE self, int interruptible_p)
rb_raise(rb_eThreadError, "deadlock; recursive locking"); rb_raise(rb_eThreadError, "deadlock; recursive locking");
} }
VALUE scheduler = rb_thread_current_scheduler();
while (mutex->fiber != fiber) { while (mutex->fiber != fiber) {
VALUE scheduler = rb_thread_current_scheduler();
if (scheduler != Qnil) { if (scheduler != Qnil) {
list_add_tail(&mutex->waitq, &w.node); list_add_tail(&mutex->waitq, &w.node);
@ -279,13 +279,8 @@ do_mutex_lock(VALUE self, int interruptible_p)
if (!mutex->fiber) { if (!mutex->fiber) {
mutex->fiber = fiber; mutex->fiber = fiber;
break; }
} else { } else {
// Try again...
continue;
}
}
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);
@ -325,6 +320,7 @@ do_mutex_lock(VALUE self, int interruptible_p)
th->status = prev_status; th->status = prev_status;
} }
rb_ractor_sleeper_threads_dec(th->ractor); rb_ractor_sleeper_threads_dec(th->ractor);
}
if (interruptible_p) { if (interruptible_p) {
/* release mutex before checking for interrupts...as interrupt checking /* release mutex before checking for interrupts...as interrupt checking