зеркало из https://github.com/github/ruby.git
[Bug #20708] Retry `open` on EINTR
Co-Authored-By: Martin Dorey <martin.dorey@hds.com>
This commit is contained in:
Родитель
ade240e578
Коммит
37d7ae06af
5
io.c
5
io.c
|
@ -6956,7 +6956,10 @@ sysopen_func(void *ptr)
|
||||||
static inline int
|
static inline int
|
||||||
rb_sysopen_internal(struct sysopen_struct *data)
|
rb_sysopen_internal(struct sysopen_struct *data)
|
||||||
{
|
{
|
||||||
int fd = IO_WITHOUT_GVL_INT(sysopen_func, data);
|
int fd;
|
||||||
|
do {
|
||||||
|
fd = IO_WITHOUT_GVL_INT(sysopen_func, data);
|
||||||
|
} while (fd < 0 && errno == EINTR);
|
||||||
if (0 <= fd)
|
if (0 <= fd)
|
||||||
rb_update_max_fd(fd);
|
rb_update_max_fd(fd);
|
||||||
return fd;
|
return fd;
|
||||||
|
|
|
@ -3876,8 +3876,10 @@ __END__
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_open_fifo_does_not_block_other_threads
|
def test_open_fifo_does_not_block_other_threads
|
||||||
mkcdtmpdir {
|
mkcdtmpdir do
|
||||||
File.mkfifo("fifo")
|
File.mkfifo("fifo")
|
||||||
|
rescue NotImplementedError
|
||||||
|
else
|
||||||
assert_separately([], <<-'EOS')
|
assert_separately([], <<-'EOS')
|
||||||
t1 = Thread.new {
|
t1 = Thread.new {
|
||||||
open("fifo", "r") {|r|
|
open("fifo", "r") {|r|
|
||||||
|
@ -3892,8 +3894,32 @@ __END__
|
||||||
t1_value, _ = assert_join_threads([t1, t2])
|
t1_value, _ = assert_join_threads([t1, t2])
|
||||||
assert_equal("foo", t1_value)
|
assert_equal("foo", t1_value)
|
||||||
EOS
|
EOS
|
||||||
}
|
end
|
||||||
end if /mswin|mingw|bccwin|cygwin/ !~ RUBY_PLATFORM
|
end
|
||||||
|
|
||||||
|
def test_open_fifo_restart_at_signal_intterupt
|
||||||
|
mkcdtmpdir do
|
||||||
|
File.mkfifo("fifo")
|
||||||
|
rescue NotImplementedError
|
||||||
|
else
|
||||||
|
wait = EnvUtil.apply_timeout_scale(0.1)
|
||||||
|
data = "writing to fifo"
|
||||||
|
|
||||||
|
# Do not use assert_separately, because reading from stdin
|
||||||
|
# prevents to reproduce [Bug #20708]
|
||||||
|
assert_in_out_err(["-e", "#{<<~"begin;"}\n#{<<~'end;'}"], [], [data])
|
||||||
|
wait, data = #{wait}, #{data.dump}
|
||||||
|
;
|
||||||
|
begin;
|
||||||
|
trap(:USR1) {}
|
||||||
|
Thread.new do
|
||||||
|
sleep wait; Process.kill(:USR1, $$)
|
||||||
|
sleep wait; File.write("fifo", data)
|
||||||
|
end
|
||||||
|
puts File.read("fifo")
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
end if Signal.list[:USR1] # Pointless on platforms without signal
|
||||||
|
|
||||||
def test_open_flag
|
def test_open_flag
|
||||||
make_tempfile do |t|
|
make_tempfile do |t|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче