summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--io.c40
-rw-r--r--rubyio.h2
3 files changed, 47 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index a460911428..303f381408 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Mon Jul 18 09:36:25 2005 Tanaka Akira <akr@m17n.org>
+
+ * rubyio.h (FMODE_WSPLIT, FMODE_WSPLIT_INITIALIZED): new constant.
+
+ * io.c (wsplit_p): new function.
+ (io_fflush): split writing data by PIPE_BUF if wsplit_p is true in
+ multi-threaded mode.
+ (io_fwrite): ditto.
+
Mon Jul 18 05:00:00 2005 NARUSE, Yui <naruse@ruby-lang.org>
* ext/nkf/nkf-utf8/nkf.c: import nkf.c 1.73
diff --git a/io.c b/io.c
index 6546e75212..116dc5c55f 100644
--- a/io.c
+++ b/io.c
@@ -373,10 +373,28 @@ io_alloc(klass)
}
static int
+wsplit_p(OpenFile *fptr)
+{
+ int r;
+ if (!(fptr->mode & FMODE_WSPLIT_INITIALIZED)) {
+ struct stat buf;
+ if (fstat(fptr->fd, &buf) == 0 &&
+ !(S_ISREG(buf.st_mode) ||
+ S_ISDIR(buf.st_mode)) &&
+ (r = fcntl(fptr->fd, F_GETFL)) != -1 &&
+ !(r & O_NONBLOCK)) {
+ fptr->mode |= FMODE_WSPLIT;
+ }
+ fptr->mode |= FMODE_WSPLIT_INITIALIZED;
+ }
+ return fptr->mode & FMODE_WSPLIT;
+}
+
+static int
io_fflush(fptr)
OpenFile *fptr;
{
- int r;
+ int r, l;
int wbuf_off, wbuf_len;
rb_io_check_closed(fptr);
@@ -390,8 +408,15 @@ io_fflush(fptr)
return 0;
wbuf_off = fptr->wbuf_off;
wbuf_len = fptr->wbuf_len;
+ l = fptr->wbuf_len;
+ if (PIPE_BUF < l &&
+ !rb_thread_critical &&
+ !rb_thread_alone() &&
+ wsplit_p(fptr)) {
+ l = PIPE_BUF;
+ }
TRAP_BEG;
- r = write(fptr->fd, fptr->wbuf+fptr->wbuf_off, fptr->wbuf_len);
+ r = write(fptr->fd, fptr->wbuf+fptr->wbuf_off, l);
TRAP_END; /* xxx: signal handler may modify wbuf */
if (r == fptr->wbuf_len) {
fptr->wbuf_off = 0;
@@ -504,7 +529,7 @@ io_fwrite(str, fptr)
VALUE str;
OpenFile *fptr;
{
- long len, n, r, offset = 0;
+ long len, n, r, l, offset = 0;
len = RSTRING(str)->len;
if ((n = len) <= 0) return n;
@@ -537,8 +562,15 @@ io_fwrite(str, fptr)
rb_io_check_closed(fptr);
}
retry:
+ l = n;
+ if (PIPE_BUF < l &&
+ !rb_thread_critical &&
+ !rb_thread_alone() &&
+ wsplit_p(fptr)) {
+ l = PIPE_BUF;
+ }
TRAP_BEG;
- r = write(fptr->fd, RSTRING(str)->ptr+offset, n);
+ r = write(fptr->fd, RSTRING(str)->ptr+offset, l);
TRAP_END; /* xxx: signal handler may modify given string. */
if (r == n) return len;
if (0 <= r) {
diff --git a/rubyio.h b/rubyio.h
index a041d90ebc..cdfd8c797f 100644
--- a/rubyio.h
+++ b/rubyio.h
@@ -48,6 +48,8 @@ typedef struct OpenFile {
#define FMODE_SYNC 8
#define FMODE_TTY 16
#define FMODE_DUPLEX 32
+#define FMODE_WSPLIT 0x200
+#define FMODE_WSPLIT_INITIALIZED 0x400
#define GetOpenFile(obj,fp) rb_io_check_closed((fp) = RFILE(rb_io_taint_check(obj))->fptr)