Bug #1460
IO#select returns wrong fd list after Kernel#sleep (Windows)
| Status: | Rejected | Start date: | 05/12/2009 | |
|---|---|---|---|---|
| Priority: | Normal | Due date: | ||
| Assignee: | % Done: | 0% |
||
| Category: | core | |||
| Target version: | Ruby 1.8.6 | |||
| ruby -v: | ruby 1.8.6 (2008-08-11 patchlevel 287) [i386-mswin32] |
Description
The following script never ends on Windows XP/Vista:
require 'thread'
a = IO.pipe
puts "pipe: #{a.inspect}"
th = Thread.new do
if res = IO.select([a[0]], [], [], 1)
puts "select ok: #{res.inspect}"
c = a[0].read(1)
puts "read ok: #{c}"
else
puts "timeout"
end
end
puts "sleep"
sleep(1)
puts "done"
The main thread stops at "sleep(1)" and the secondary thread at "c = a[0].read(1)". This is the output I get:
pipe: [#<IO:0x2b616f4>, #<IO:0x2b616cc>]
sleep
select ok: [[#<IO:0x2b616f4>], [], []]
(ruby freezes here)
The Kernel#sleep call makes IO#select return with the pipe handle, even though it hasn't signaled. Then the call to IO#read blocks because no data is available. I couldn't come up with a workaround because IO#read_nonblock does not work with pipes in Windows (raises "Bad file descriptor" (calling IO#fcntl with O_NONBLOCK is also not possible)).
History
Updated by nobu (Nobuyoshi Nakada) about 3 years ago
- Status changed from Open to Assigned
- Assignee set to usa (Usaku NAKAMURA)
Don't use IO.select with pipes. It's a known restriction. If you really need to it, use 1.8.7.
Updated by usa (Usaku NAKAMURA) about 3 years ago
- Status changed from Assigned to Rejected