mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* io.c (rb_io_wait_readable, rb_io_wait_writable): check if the file
descriptor is closed. * thread.c (rb_thread_wait_fd_rw): ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@18027 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
4532c0d81e
commit
f3fcd2e4a0
5 changed files with 53 additions and 16 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
Fri Jul 11 20:51:36 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* io.c (rb_io_wait_readable, rb_io_wait_writable): check if the file
|
||||||
|
descriptor is closed.
|
||||||
|
|
||||||
|
* thread.c (rb_thread_wait_fd_rw): ditto.
|
||||||
|
|
||||||
Fri Jul 11 16:16:43 2008 NAKAMURA Usaku <usa@ruby-lang.org>
|
Fri Jul 11 16:16:43 2008 NAKAMURA Usaku <usa@ruby-lang.org>
|
||||||
|
|
||||||
* win32/win32.c (rb_w32_accept, rb_w32_socket, rb_w32_socketpair):
|
* win32/win32.c (rb_w32_accept, rb_w32_socket, rb_w32_socketpair):
|
||||||
|
|
|
@ -188,7 +188,7 @@ def assert_valid_syntax(testsrc, message = '')
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def assert_normal_exit(testsrc, message = '')
|
def assert_normal_exit(testsrc, message = '', ignore_signals = nil)
|
||||||
newtest
|
newtest
|
||||||
$stderr.puts "\##{@count} #{@location}" if @verbose
|
$stderr.puts "\##{@count} #{@location}" if @verbose
|
||||||
faildesc = nil
|
faildesc = nil
|
||||||
|
@ -205,28 +205,33 @@ def assert_normal_exit(testsrc, message = '')
|
||||||
if status.signaled?
|
if status.signaled?
|
||||||
signo = status.termsig
|
signo = status.termsig
|
||||||
signame = Signal.list.invert[signo]
|
signame = Signal.list.invert[signo]
|
||||||
sigdesc = "signal #{signo}"
|
unless ignore_signals and ignore_signals.include?(signame)
|
||||||
if signame
|
sigdesc = "signal #{signo}"
|
||||||
sigdesc = "SIG#{signame} (#{sigdesc})"
|
if signame
|
||||||
end
|
sigdesc = "SIG#{signame} (#{sigdesc})"
|
||||||
faildesc = pretty(testsrc, "killed by #{sigdesc}", nil)
|
end
|
||||||
stderr_log = File.read("assert_normal_exit_stderr.log")
|
faildesc = pretty(testsrc, "killed by #{sigdesc}", nil)
|
||||||
if !stderr_log.empty?
|
stderr_log = File.read("assert_normal_exit_stderr.log")
|
||||||
faildesc << "\n" if /\n\z/ !~ faildesc
|
if !stderr_log.empty?
|
||||||
stderr_log << "\n" if /\n\z/ !~ stderr_log
|
faildesc << "\n" if /\n\z/ !~ faildesc
|
||||||
stderr_log.gsub!(/^.*\n/) { '| ' + $& }
|
stderr_log << "\n" if /\n\z/ !~ stderr_log
|
||||||
faildesc << stderr_log
|
stderr_log.gsub!(/^.*\n/) { '| ' + $& }
|
||||||
|
faildesc << stderr_log
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if !faildesc
|
if !faildesc
|
||||||
$stderr.print '.'
|
$stderr.print '.'
|
||||||
|
true
|
||||||
else
|
else
|
||||||
$stderr.print 'F'
|
$stderr.print 'F'
|
||||||
error faildesc, message
|
error faildesc, message
|
||||||
|
false
|
||||||
end
|
end
|
||||||
rescue Exception => err
|
rescue Exception => err
|
||||||
$stderr.print 'E'
|
$stderr.print 'E'
|
||||||
error err.message, message
|
error err.message, message
|
||||||
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
def assert_finish(timeout_seconds, testsrc, message = '')
|
def assert_finish(timeout_seconds, testsrc, message = '')
|
||||||
|
|
|
@ -73,3 +73,22 @@ assert_equal 'ok', %q{
|
||||||
assert_normal_exit %q{
|
assert_normal_exit %q{
|
||||||
ARGF.set_encoding "foo"
|
ARGF.set_encoding "foo"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
50.times do
|
||||||
|
assert_normal_exit %q{
|
||||||
|
at_exit { p :foo }
|
||||||
|
|
||||||
|
megacontent = "abc" * 12345678
|
||||||
|
File.open("megasrc", "w") {|f| f << megacontent }
|
||||||
|
|
||||||
|
Thread.new { sleep rand*0.2; Process.kill(:INT, $$) }
|
||||||
|
|
||||||
|
r1, w1 = IO.pipe
|
||||||
|
r2, w2 = IO.pipe
|
||||||
|
t1 = Thread.new { w1 << megacontent; w1.close }
|
||||||
|
t2 = Thread.new { r2.read }
|
||||||
|
IO.copy_stream(r1, w2) rescue nil
|
||||||
|
r2.close; w2.close
|
||||||
|
r1.close; w1.close
|
||||||
|
}, '', ["INT"] or break
|
||||||
|
end
|
||||||
|
|
11
io.c
11
io.c
|
@ -608,6 +608,9 @@ rb_io_wait_readable(int f)
|
||||||
{
|
{
|
||||||
rb_fdset_t rfds;
|
rb_fdset_t rfds;
|
||||||
|
|
||||||
|
if (f < 0) {
|
||||||
|
rb_raise(rb_eIOError, "closed stream");
|
||||||
|
}
|
||||||
switch (errno) {
|
switch (errno) {
|
||||||
case EINTR:
|
case EINTR:
|
||||||
#if defined(ERESTART)
|
#if defined(ERESTART)
|
||||||
|
@ -650,6 +653,9 @@ rb_io_wait_writable(int f)
|
||||||
{
|
{
|
||||||
rb_fdset_t wfds;
|
rb_fdset_t wfds;
|
||||||
|
|
||||||
|
if (f < 0) {
|
||||||
|
rb_raise(rb_eIOError, "closed stream");
|
||||||
|
}
|
||||||
switch (errno) {
|
switch (errno) {
|
||||||
case EINTR:
|
case EINTR:
|
||||||
#if defined(ERESTART)
|
#if defined(ERESTART)
|
||||||
|
@ -1484,11 +1490,8 @@ io_getpartial(int argc, VALUE *argv, VALUE io, int nonblock)
|
||||||
if (RSTRING_LEN(str) != len) goto modified;
|
if (RSTRING_LEN(str) != len) goto modified;
|
||||||
if (nonblock) {
|
if (nonblock) {
|
||||||
rb_io_set_nonblock(fptr);
|
rb_io_set_nonblock(fptr);
|
||||||
n = rb_read_internal(fptr->fd, RSTRING_PTR(str), len);
|
|
||||||
}
|
}
|
||||||
else {
|
n = rb_read_internal(fptr->fd, RSTRING_PTR(str), len);
|
||||||
n = rb_read_internal(fptr->fd, RSTRING_PTR(str), len);
|
|
||||||
}
|
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
if (!nonblock && rb_io_wait_readable(fptr->fd))
|
if (!nonblock && rb_io_wait_readable(fptr->fd))
|
||||||
goto again;
|
goto again;
|
||||||
|
|
3
thread.c
3
thread.c
|
@ -2018,6 +2018,9 @@ rb_thread_wait_fd_rw(int fd, int read)
|
||||||
int result = 0;
|
int result = 0;
|
||||||
thread_debug("rb_thread_wait_fd_rw(%d, %s)\n", fd, read ? "read" : "write");
|
thread_debug("rb_thread_wait_fd_rw(%d, %s)\n", fd, read ? "read" : "write");
|
||||||
|
|
||||||
|
if (fd < 0) {
|
||||||
|
rb_raise(rb_eIOError, "closed stream");
|
||||||
|
}
|
||||||
while (result <= 0) {
|
while (result <= 0) {
|
||||||
rb_fdset_t set;
|
rb_fdset_t set;
|
||||||
rb_fd_init(&set);
|
rb_fd_init(&set);
|
||||||
|
|
Loading…
Reference in a new issue