summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--bootstraptest/test_io.rb16
-rw-r--r--bootstraptest/test_knownbug.rb15
-rw-r--r--io.c77
4 files changed, 69 insertions, 45 deletions
diff --git a/ChangeLog b/ChangeLog
index d7f8e744d3..a9aeb3a46f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Fri Dec 21 18:40:54 2007 Koichi Sasada <ko1@atdot.net>
+
+ * io.c: write() should be in blocking region.
+
+ * bootstraptest/test_io.rb, test_knownbug.rb: move a fixed test.
+
Fri Dec 21 17:56:30 2007 <nagai@orca16.orcabay.ddo.jp>
* ext/tk/tcltklib.c: provisional support on Ruby-VM.
diff --git a/bootstraptest/test_io.rb b/bootstraptest/test_io.rb
index e62b9d15a2..20a441de9f 100644
--- a/bootstraptest/test_io.rb
+++ b/bootstraptest/test_io.rb
@@ -7,3 +7,19 @@ assert_finish 5, %q{
sleep 0.1
w.write "a"
}, '[ruby-dev:31866]'
+
+assert_finish 10, %q{
+ require "io/nonblock"
+ r, w = IO.pipe
+ w.nonblock = true
+ w.write_nonblock("a" * 100000)
+ w.nonblock = false
+ t1 = Thread.new { w.write("b" * 4096) }
+ t2 = Thread.new { w.write("c" * 4096) }
+ sleep 0.5
+ r.sysread(4096).length
+ sleep 0.5
+ r.sysread(4096).length
+ t1.join
+ t2.join
+}, '[ruby-dev:32566]'
diff --git a/bootstraptest/test_knownbug.rb b/bootstraptest/test_knownbug.rb
index 3d3f4dbd2a..b97a08d928 100644
--- a/bootstraptest/test_knownbug.rb
+++ b/bootstraptest/test_knownbug.rb
@@ -3,18 +3,3 @@
# So all tests will cause failure.
#
-assert_finish 2, %q{
- require "io/nonblock"
- r, w = IO.pipe
- w.nonblock = true
- w.write_nonblock("a" * 100000)
- w.nonblock = false
- t1 = Thread.new { w.write("b" * 4096) }
- t2 = Thread.new { w.write("c" * 4096) }
- sleep 0.5
- r.sysread(4096).length
- sleep 0.5
- r.sysread(4096).length
- t1.join
- t2.join
-}, '[ruby-dev:32566]'
diff --git a/io.c b/io.c
index 949b0212a7..659784a777 100644
--- a/io.c
+++ b/io.c
@@ -455,6 +455,49 @@ wsplit_p(rb_io_t *fptr)
return fptr->mode & FMODE_WSPLIT;
}
+struct io_internal_struct {
+ int fd;
+ void *buf;
+ size_t capa;
+ int is_read;
+};
+
+static VALUE
+internal_io_func(void *ptr)
+{
+ struct io_internal_struct *iis = (struct io_internal_struct*)ptr;
+ if (iis->is_read) {
+ return read(iis->fd, iis->buf, iis->capa);
+ }
+ else {
+ return write(iis->fd, iis->buf, iis->capa);
+ }
+}
+
+static int
+rb_read_internal(int fd, void *buf, size_t count)
+{
+ struct io_internal_struct iis;
+ iis.fd = fd;
+ iis.buf = buf;
+ iis.capa = count;
+ iis.is_read = 1;
+
+ return rb_thread_blocking_region(internal_io_func, &iis, RB_UBF_DFL, 0);
+}
+
+static int
+rb_write_internal(int fd, void *buf, size_t count)
+{
+ struct io_internal_struct iis;
+ iis.fd = fd;
+ iis.buf = buf;
+ iis.capa = count;
+ iis.is_read = 0;
+
+ return rb_thread_blocking_region(internal_io_func, &iis, RB_UBF_DFL, 0);
+}
+
static int
io_fflush(rb_io_t *fptr)
{
@@ -479,9 +522,8 @@ io_fflush(rb_io_t *fptr)
wsplit_p(fptr)) {
l = PIPE_BUF;
}
- TRAP_BEG;
- r = write(fptr->fd, fptr->wbuf+fptr->wbuf_off, l);
- TRAP_END; /* xxx: signal handler may modify wbuf */
+ r = rb_write_internal(fptr->fd, fptr->wbuf+fptr->wbuf_off, l);
+ /* xxx: signal handler may modify wbuf */
if (r == fptr->wbuf_len) {
fptr->wbuf_off = 0;
fptr->wbuf_len = 0;
@@ -627,9 +669,8 @@ io_fwrite(VALUE str, rb_io_t *fptr)
wsplit_p(fptr)) {
l = PIPE_BUF;
}
- TRAP_BEG;
- r = write(fptr->fd, RSTRING_PTR(str)+offset, l);
- TRAP_END; /* xxx: signal handler may modify given string. */
+ r = rb_write_internal(fptr->fd, RSTRING_PTR(str)+offset, l);
+ /* xxx: signal handler may modify given string. */
if (r == n) return len;
if (0 <= r) {
offset += r;
@@ -905,30 +946,6 @@ rb_io_rewind(VALUE io)
return INT2FIX(0);
}
-struct read_struct {
- int fd;
- void *buf;
- size_t capa;
-};
-
-static VALUE
-read_func(void *ptr)
-{
- struct read_struct *rs = (struct read_struct*)ptr;
- return read(rs->fd, rs->buf, rs->capa);
-}
-
-
-static int
-rb_read_internal(int fd, void *buf, size_t count)
-{
- struct read_struct rs;
- rs.fd = fd;
- rs.buf = buf;
- rs.capa = count;
- return rb_thread_blocking_region(read_func, &rs, RB_UBF_DFL, 0);
-}
-
static int
io_fillbuf(rb_io_t *fptr)
{