From 31ee6b4daa1da9cd02e75b27924b2729345e999d Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Tue, 29 Dec 2009 12:59:01 -0800 Subject: quiet spurious wakeups for accept() in Thread* models Under all MRI 1.8, a blocking Socket#accept Ruby method (needs to[1]) translate to a non-blocking accept(2) system call that may wake up threads/processes unnecessarily. Unfortunately, we failed to trap and ignore EAGAIN in those cases. This issue did not affect Ruby 1.9 running under modern Linux kernels where a _blocking_ accept(2) system call is not (easily, at least) susceptible to spurious wakeups. Non-Linux systems running Ruby 1.9 may be affected. [1] - using a blocking accept(2) on a shared socket with green threads is dangerous, as noted in commit ee7fe220ccbc991e1e7cbe982caf48e3303274c7 (and commit 451ca6997b4f298b436605b7f0af75f369320425) --- lib/rainbows/thread_pool.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'lib/rainbows/thread_pool.rb') diff --git a/lib/rainbows/thread_pool.rb b/lib/rainbows/thread_pool.rb index 3ef719a..a68fcc6 100644 --- a/lib/rainbows/thread_pool.rb +++ b/lib/rainbows/thread_pool.rb @@ -44,8 +44,7 @@ module Rainbows def sync_worker s = LISTENERS.first begin - process_client(s.accept) - rescue Errno::EINTR, Errno::ECONNABORTED + c = Rainbows.sync_accept(s) and process_client(c) rescue => e Error.listen_loop(e) end while G.alive -- cgit v1.2.3-24-ge0c7