[#26156] ruby 1.8.3 preview1 — Yukihiro Matsumoto <matz@...>

Hi,

28 messages 2005/05/12

[#26186] ruby_setenv dumps core with mod_ruby/1.4.2 — Tietew <tietew-ml-ruby-dev@...>

Tietew です。

15 messages 2005/05/18
[#26285] Re: ruby_setenv dumps core with mod_ruby/1.4.2 — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/06/05

山本です。

[#26325] Re: ruby_setenv dumps core with mod_ruby/1.4.2 — Tietew <tietew-ml-ruby-dev@...> 2005/06/10

Tietew です。

[#26187] IO.select dumps core — Tanaka Akira <akr@...17n.org>

[ruby-talk:142505] で可能性に気がついたのですが、いま実験してみたとこ

31 messages 2005/05/18
[#26255] Re: IO.select dumps core — nobu@... 2005/05/31

なかだです。

[#26256] Re: IO.select dumps core — Tanaka Akira <akr@...17n.org> 2005/06/01

In article <200505311523.j4VFN4Y4005876@sharui.nakada.niregi.kanuma.tochigi.jp>,

[#26257] Re: IO.select dumps core — nobu@... 2005/06/01

なかだです。

[#26262] Re: IO.select dumps core — Tanaka Akira <akr@...17n.org> 2005/06/01

In article <200506010140.j511edY4012889@sharui.nakada.niregi.kanuma.tochigi.jp>,

[#26265] Re: IO.select dumps core — Takahiro Kambe <taca@...> 2005/06/02

In message <87u0khj377.fsf@m17n.org>

[#26365] Re: IO.select dumps core — とみたまさひろ <tommy@...> 2005/06/22

とみたです。

[#26366] Re: IO.select dumps core — nobu@... 2005/06/22

なかだです。

[#26369] Re: IO.select dumps core — とみたまさひろ <tommy@...> 2005/06/23

とみたです。

[#26242] many errors with soap/wsdl test on mswin32 — "U.Nakamura" <usa@...>

こんにちは、なかむら(う)です。

12 messages 2005/05/27
[#26249] Re: many errors with soap/wsdl test on mswin32 — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/05/31

山本です。

[ruby-dev:26255] Re: IO.select dumps core

From: nobu@...
Date: 2005-05-31 15:23:07 UTC
List: ruby-dev #26255
なかだです。

At Thu, 19 May 2005 00:04:05 +0900,
Tanaka Akira wrote in [ruby-dev:26187]:
> [ruby-talk:142505] で可能性に気がついたのですが、いま実験してみたとこ
> ろ次のようにすると core を吐きます。
> 
> # ulimit -c unlimited
> # ulimit -n 2048
> # ./ruby -e 'IO.select(*(0...1000).map { IO.pipe }.transpose)'
> -e:1: [BUG] Segmentation fault
> ruby 1.9.0 (2005-05-18) [i686-linux]
> 
> Aborted (core dumped)

fd_setの実装に激しく依存するような気はしますが。


Index: eval.c
===================================================================
RCS file: /cvs/ruby/src/ruby/eval.c,v
retrieving revision 1.783
diff -U2 -p -r1.783 eval.c
--- eval.c	25 May 2005 23:33:10 -0000	1.783
+++ eval.c	31 May 2005 06:45:05 -0000
@@ -135,4 +135,8 @@ typedef jmp_buf rb_jmpbuf_t;
 #endif
 
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
 #include <sys/stat.h>
 
@@ -9772,4 +9776,92 @@ enum thread_status {
 #endif
 
+#ifdef NFDBITS
+void
+rb_fd_init(fds)
+    volatile rb_fdset_t *fds;
+{
+    fds->maxfd = 0;
+    fds->maskp = 0;
+}
+
+void
+rb_fd_term(fds)
+    rb_fdset_t *fds;
+{
+    if (fds->maskp) free(fds->maskp);
+    rb_fd_init(fds);
+}
+
+void
+rb_fd_zero(fds)
+    rb_fdset_t *fds;
+{
+    if (fds->maskp) {
+	MEMZERO(fds->maskp, fd_mask, howmany(fds->maxfd, NFDBITS));
+    }
+}
+
+void
+rb_fd_set(n, fds)
+    int n;
+    rb_fdset_t *fds;
+{
+    int m = howmany(n + 1, NFDBITS), o = howmany(fds->maxfd, NFDBITS);
+
+    if (m > o) {
+	REALLOC_N(fds->maskp, fd_mask, m);
+	MEMZERO(fds->maskp + howmany(fds->maxfd, NFDBITS), fd_mask, m - o);
+    }
+    if (n >= fds->maxfd) fds->maxfd = n + 1;
+    FD_SET(n, (fd_set *)fds->maskp);
+}
+
+void
+rb_fd_clr(n, fds)
+    int n;
+    rb_fdset_t *fds;
+{
+    if (n >= fds->maxfd) return;
+    FD_CLR(n, (fd_set *)fds->maskp);
+}
+
+int
+rb_fd_isset(n, fds)
+    int n;
+    const rb_fdset_t *fds;
+{
+    if (n >= fds->maxfd) return 0;
+    return FD_ISSET(n, (fd_set *)fds->maskp);
+}
+
+void
+rb_fd_copy(dst, src, max)
+    rb_fdset_t *dst;
+    const fd_set *src;
+    int max;
+{
+    if ((dst->maxfd = max) > 0) {
+	int n = howmany(max, NFDBITS);
+	REALLOC_N(dst->maskp, fd_mask, n);
+	MEMCPY(dst->maskp, src, fd_mask, n);
+    }
+    else {
+	xfree(dst->maskp);
+	dst->maskp = 0;
+    }
+}
+
+#undef FD_ZERO
+#undef FD_SET
+#undef FD_CLR
+#undef FD_ISSET
+
+#define FD_ZERO(f)	rb_fd_zero(f)
+#define FD_SET(i, f)	rb_fd_set(i, f)
+#define FD_CLR(i, f)	rb_fd_clr(i, f)
+#define FD_ISSET(i, f)	rb_fd_isset(i, f)
+
+#endif
+
 /* typedef struct thread * rb_thread_t; */
 
@@ -9818,7 +9910,7 @@ struct thread {
     int wait_for;
     int fd;
-    fd_set readfds;
-    fd_set writefds;
-    fd_set exceptfds;
+    rb_fdset_t readfds;
+    rb_fdset_t writefds;
+    rb_fdset_t exceptfds;
     int select_value;
     double delay;
@@ -9858,7 +9950,7 @@ struct thread_status_t {
     int wait_for;
     int fd;
-    fd_set readfds;
-    fd_set writefds;
-    fd_set exceptfds;
+    rb_fdset_t readfds;
+    rb_fdset_t writefds;
+    rb_fdset_t exceptfds;
     int select_value;
     double delay;
@@ -9883,4 +9975,7 @@ struct thread_status_t {
     (dst)->writefds = (src)->writefds,		\
     (dst)->exceptfds = (src)->exceptfds,	\
+    rb_fd_init(&(src)->readfds),		\
+    rb_fd_init(&(src)->writefds),		\
+    rb_fd_init(&(src)->exceptfds),		\
     (dst)->select_value = (src)->select_value,	\
     (dst)->delay = (src)->delay,		\
@@ -10434,5 +10529,5 @@ rb_thread_deadlock()
 static void
 copy_fds(dst, src, max)
-    fd_set *dst, *src;
+    rb_fdset_t *dst, *src;
     int max;
 {
@@ -10440,4 +10535,5 @@ copy_fds(dst, src, max)
     int i;
 
+    if (max >= rb_fd_max(src)) max = rb_fd_max(src) - 1;
     for (i=0; i<=max; i++) {
 	if (FD_ISSET(i, src)) {
@@ -10450,9 +10546,11 @@ copy_fds(dst, src, max)
 static int
 match_fds(dst, src, max)
-    fd_set *dst, *src;
+    rb_fdset_t *dst, *src;
     int max;
 {
     int i;
 
+    if (max >= rb_fd_max(src)) max = rb_fd_max(src) - 1;
+    if (max >= rb_fd_max(dst)) max = rb_fd_max(dst) - 1;
     for (i=0; i<=max; i++) {
 	if (FD_ISSET(i, src) && FD_ISSET(i, dst)) {
@@ -10465,9 +10563,10 @@ match_fds(dst, src, max)
 static int
 intersect_fds(src, dst, max)
-    fd_set *src, *dst;
+    rb_fdset_t *src, *dst;
     int max;
 {
     int i, n = 0;
 
+    if (max >= rb_fd_max(dst)) max = rb_fd_max(dst) - 1;
     for (i=0; i<=max; i++) {
 	if (FD_ISSET(i, dst)) {
@@ -10487,9 +10586,10 @@ intersect_fds(src, dst, max)
 static int
 find_bad_fds(dst, src, max)
-    fd_set *dst, *src;
+    rb_fdset_t *dst, *src;
     int max;
 {
     int i, test = Qfalse;
 
+    if (max >= rb_fd_max(src)) max = rb_fd_max(src) - 1;
     for (i=0; i<=max; i++) {
 	if (FD_ISSET(i, src) && !FD_ISSET(i, dst)) {
@@ -10509,7 +10609,7 @@ rb_thread_schedule()
     int found = 0;
 
-    fd_set readfds;
-    fd_set writefds;
-    fd_set exceptfds;
+    rb_fdset_t readfds;
+    rb_fdset_t writefds;
+    rb_fdset_t exceptfds;
     struct timeval delay_tv, *delay_ptr;
     double delay, now;	/* OK */
@@ -10535,4 +10635,8 @@ rb_thread_schedule()
     }
 
+    rb_fd_init(&readfds);
+    rb_fd_init(&writefds);
+    rb_fd_init(&exceptfds);
+
   again:
     max = -1;
@@ -10608,9 +10712,18 @@ rb_thread_schedule()
 	}
 
-	n = select(max+1, &readfds, &writefds, &exceptfds, delay_ptr);
+	n = select(max+1, rb_fd_ptr(&readfds), rb_fd_ptr(&writefds), rb_fd_ptr(&exceptfds), delay_ptr);
 	if (n < 0) {
 	    int e = errno;
 
-	    if (rb_trap_pending) rb_trap_exec();
+	    if (rb_trap_pending) {
+		int status;
+		rb_protect((VALUE (*)_((VALUE)))rb_trap_exec, Qnil, &status);
+		if (status) {
+		    rb_fd_term(&readfds);
+		    rb_fd_term(&writefds);
+		    rb_fd_term(&exceptfds);
+		    rb_jump_tag(status);
+		}
+	    }
 	    if (e == EINTR) goto again;
 #ifdef ERESTART
@@ -10683,4 +10796,8 @@ rb_thread_schedule()
     }
 
+    rb_fd_term(&readfds);
+    rb_fd_term(&writefds);
+    rb_fd_term(&exceptfds);
+
     FOREACH_THREAD_FROM(curr, th) {
 	if (th->status == THREAD_TO_KILL) {
@@ -10910,9 +11027,9 @@ rb_thread_select(max, read, write, excep
 
     curr_thread->status = THREAD_STOPPED;
-    if (read) curr_thread->readfds = *read;
+    if (read) rb_fd_copy(&curr_thread->readfds, read, max);
     else FD_ZERO(&curr_thread->readfds);
-    if (write) curr_thread->writefds = *write;
+    if (write) rb_fd_copy(&curr_thread->writefds, write, max);
     else FD_ZERO(&curr_thread->writefds);
-    if (except) curr_thread->exceptfds = *except;
+    if (except) rb_fd_copy(&curr_thread->exceptfds, except, max);
     else FD_ZERO(&curr_thread->exceptfds);
     curr_thread->fd = max;
@@ -10924,7 +11041,7 @@ rb_thread_select(max, read, write, excep
     }
     rb_thread_schedule();
-    if (read) *read = curr_thread->readfds;
-    if (write) *write = curr_thread->writefds;
-    if (except) *except = curr_thread->exceptfds;
+    if (read) *read = *rb_fd_ptr(&curr_thread->readfds);
+    if (write) *write = *rb_fd_ptr(&curr_thread->writefds);
+    if (except) *except = *rb_fd_ptr(&curr_thread->exceptfds);
     return curr_thread->select_value;
 }
@@ -11568,7 +11685,7 @@ rb_thread_group(thread)
     IA64_INIT(th->bstr_ptr = 0);\
     IA64_INIT(th->bstr_len = 0);\
-    FD_ZERO(&th->readfds);\
-    FD_ZERO(&th->writefds);\
-    FD_ZERO(&th->exceptfds);\
+    rb_fd_init(&th->readfds);\
+    rb_fd_init(&th->writefds);\
+    rb_fd_init(&th->exceptfds);\
     th->delay = 0.0;\
     th->join = 0;\
Index: intern.h
===================================================================
RCS file: /cvs/ruby/src/ruby/intern.h,v
retrieving revision 1.168
diff -U2 -p -r1.168 intern.h
--- intern.h	22 May 2005 03:31:08 -0000	1.168
+++ intern.h	31 May 2005 06:44:32 -0000
@@ -146,4 +146,38 @@ NORETURN(void rb_error_frozen _((const c
 void rb_check_frozen _((VALUE));
 /* eval.c */
+#ifdef NFDBITS
+typedef struct {
+    int maxfd;
+    fd_mask *maskp;
+} rb_fdset_t;
+
+#define HAVE_RB_FD_INIT 1
+
+void rb_fd_init _((volatile rb_fdset_t *));
+void rb_fd_term _((rb_fdset_t *));
+void rb_fd_zero _((rb_fdset_t *));
+void rb_fd_set _((int, rb_fdset_t *));
+void rb_fd_clr _((int, rb_fdset_t *));
+int rb_fd_isset _((int, const rb_fdset_t *));
+void rb_fd_copy _((rb_fdset_t *, const fd_set *, int));
+
+#define rb_fd_ptr(f)	((fd_set *)(f)->maskp)
+#define rb_fd_max(f)	((f)->maxfd)
+
+#else
+
+typedef fd_set rb_fdset_t;
+#define rb_fd_zero(f)	FD_ZERO(f)
+#define rb_fd_set(n, f)	FD_SET(n, f)
+#define rb_fd_clr(n, f)	FD_CLR(n, f)
+#define rb_fd_isset(n, f) FD_ISSET(n, f)
+#define rb_fd_copy(d, s, n) (*(d) = *(s))
+#define rb_fd_ptr(f)	(f)
+#define rb_fd_init(f)	FD_ZERO(f)
+#define rb_fd_term(f)	(f)
+#define rb_fd_max(f)	FD_SETSIZE
+
+#endif
+
 RUBY_EXTERN struct RNode *ruby_current_node;
 void ruby_set_current_source _((void));
Index: io.c
===================================================================
RCS file: /cvs/ruby/src/ruby/io.c,v
retrieving revision 1.366
diff -U2 -p -r1.366 io.c
--- io.c	7 Mar 2005 02:05:07 -0000	1.366
+++ io.c	31 May 2005 06:03:50 -0000
@@ -411,9 +411,20 @@ io_fflush(fptr)
 }
 
+#ifdef HAVE_RB_FD_INIT
+static VALUE
+wait_readable(p)
+    VALUE p;
+{
+    rb_fdset_t *rfds = (rb_fdset_t *)p;
+
+    return rb_thread_select(rb_fd_max(rfds), rb_fd_ptr(rfds), NULL, NULL, NULL);
+}
+#endif
+
 int
 rb_io_wait_readable(f)
     int f;
 {
-    fd_set rfds;
+    rb_fdset_t rfds;
 
     switch (errno) {
@@ -429,7 +440,12 @@ rb_io_wait_readable(f)
       case EWOULDBLOCK:
 #endif
-	FD_ZERO(&rfds);
-	FD_SET(f, &rfds);
+	rb_fd_init(&rfds);
+	rb_fd_set(f, &rfds);
+#ifdef HAVE_RB_FD_INIT
+	rb_ensure(wait_readable, (VALUE)&rfds,
+		  (VALUE (*)_((VALUE)))rb_fd_zero, (VALUE)&rfds);
+#else
 	rb_thread_select(f + 1, &rfds, NULL, NULL, NULL);
+#endif
 	return Qtrue;
 
@@ -439,9 +455,20 @@ rb_io_wait_readable(f)
 }
 
+#ifdef HAVE_RB_FD_INIT
+static VALUE
+wait_writable(p)
+    VALUE p;
+{
+    rb_fdset_t *wfds = (rb_fdset_t *)p;
+
+    return rb_thread_select(rb_fd_max(wfds), NULL, rb_fd_ptr(wfds), NULL, NULL);
+}
+#endif
+
 int
 rb_io_wait_writable(f)
     int f;
 {
-    fd_set wfds;
+    rb_fdset_t wfds;
 
     switch (errno) {
@@ -457,7 +484,12 @@ rb_io_wait_writable(f)
       case EWOULDBLOCK:
 #endif
-	FD_ZERO(&wfds);
-	FD_SET(f, &wfds);
+	rb_fd_init(&wfds);
+	rb_fd_set(f, &wfds);
+#ifdef HAVE_RB_FD_INIT
+	rb_ensure(wait_writable, (VALUE)&wfds,
+		  (VALUE (*)_((VALUE)))rb_fd_zero, (VALUE)&wfds);
+#else
 	rb_thread_select(f + 1, NULL, &wfds, NULL, NULL);
+#endif
 	return Qtrue;
 
@@ -2618,9 +2650,9 @@ rb_fdopen(fd, mode)
     file = fdopen(fd, mode);
     if (!file) {
+	if (
 #if defined(sun)
-	if (errno == 0 || errno == EMFILE || errno == ENFILE) {
-#else
-	if (errno == EMFILE || errno == ENFILE) {
+	    errno == 0 ||
 #endif
+	    errno == EMFILE || errno == ENFILE) {
 	    rb_gc();
 #if defined(sun)
@@ -4512,24 +4544,12 @@ rb_f_backquote(obj, str)
 #endif
 
-/*
- *  call-seq:
- *     IO.select(read_array
- *               [, write_array
- *               [, error_array
- *               [, timeout]]] ) =>  array  or  nil
- *
- *  See <code>Kernel#select</code>.
- */
-
 static VALUE
-rb_f_select(argc, argv, obj)
-    int argc;
-    VALUE *argv;
-    VALUE obj;
+select_internal(read, write, except, tp, fds)
+    VALUE read, write, except;
+    struct timeval *tp;
+    rb_fdset_t *fds;
 {
-    VALUE read, write, except, timeout, res, list;
-    fd_set rset, wset, eset, pset;
+    VALUE res, list;
     fd_set *rp, *wp, *ep;
-    struct timeval *tp, timerec;
     OpenFile *fptr;
     long i;
@@ -4537,25 +4557,14 @@ rb_f_select(argc, argv, obj)
     int interrupt_flag = 0;
     int pending = 0;
+    struct timeval timerec;
 
-    rb_scan_args(argc, argv, "13", &read, &write, &except, &timeout);
-    if (NIL_P(timeout)) {
-	tp = 0;
-    }
-    else {
-	timerec = rb_time_interval(timeout);
-	tp = &timerec;
-    }
-
-    FD_ZERO(&pset);
     if (!NIL_P(read)) {
 	Check_Type(read, T_ARRAY);
-	rp = &rset;
-	FD_ZERO(rp);
 	for (i=0; i<RARRAY(read)->len; i++) {
 	    GetOpenFile(rb_io_get_io(RARRAY(read)->ptr[i]), fptr);
-	    FD_SET(fptr->fd, rp);
+	    rb_fd_set(fptr->fd, &fds[0]);
 	    if (READ_DATA_PENDING(fptr)) { /* check for buffered data */
 		pending++;
-		FD_SET(fptr->fd, &pset);
+		rb_fd_set(fptr->fd, &fds[3]);
 	    }
 	    if (max < fptr->fd) max = fptr->fd;
@@ -4565,4 +4574,5 @@ rb_f_select(argc, argv, obj)
 	    tp = &timerec;
 	}
+	rp = rb_fd_ptr(&fds[0]);
     }
     else
@@ -4571,11 +4581,10 @@ rb_f_select(argc, argv, obj)
     if (!NIL_P(write)) {
 	Check_Type(write, T_ARRAY);
-	wp = &wset;
-	FD_ZERO(wp);
 	for (i=0; i<RARRAY(write)->len; i++) {
 	    GetOpenFile(rb_io_get_io(RARRAY(write)->ptr[i]), fptr);
-	    FD_SET(fptr->fd, wp);
+	    rb_fd_set(fptr->fd, &fds[1]);
 	    if (max < fptr->fd) max = fptr->fd;
 	}
+	wp = rb_fd_ptr(&fds[1]);
     }
     else
@@ -4584,11 +4593,10 @@ rb_f_select(argc, argv, obj)
     if (!NIL_P(except)) {
 	Check_Type(except, T_ARRAY);
-	ep = &eset;
-	FD_ZERO(ep);
 	for (i=0; i<RARRAY(except)->len; i++) {
 	    GetOpenFile(rb_io_get_io(RARRAY(except)->ptr[i]), fptr);
-	    FD_SET(fptr->fd, ep);
+	    rb_fd_set(fptr->fd, &fds[2]);
 	    if (max < fptr->fd) max = fptr->fd;
 	}
+	ep = rb_fd_ptr(&fds[2]);
     }
     else {
@@ -4614,6 +4622,6 @@ rb_f_select(argc, argv, obj)
 	    for (i=0; i< RARRAY(read)->len; i++) {
 		GetOpenFile(rb_io_get_io(RARRAY(read)->ptr[i]), fptr);
-		if (FD_ISSET(fptr->fd, rp)
-		    || FD_ISSET(fptr->fd, &pset)) {
+		if (rb_fd_isset(fptr->fd, &fds[0]) ||
+		    rb_fd_isset(fptr->fd, &fds[3])) {
 		    rb_ary_push(list, rb_ary_entry(read, i));
 		}
@@ -4625,5 +4633,5 @@ rb_f_select(argc, argv, obj)
 	    for (i=0; i< RARRAY(write)->len; i++) {
 		GetOpenFile(rb_io_get_io(RARRAY(write)->ptr[i]), fptr);
-		if (FD_ISSET(fptr->fd, wp)) {
+		if (rb_fd_isset(fptr->fd, &fds[1])) {
 		    rb_ary_push(list, rb_ary_entry(write, i));
 		}
@@ -4635,5 +4643,5 @@ rb_f_select(argc, argv, obj)
 	    for (i=0; i< RARRAY(except)->len; i++) {
 		GetOpenFile(rb_io_get_io(RARRAY(except)->ptr[i]), fptr);
-		if (FD_ISSET(fptr->fd, ep)) {
+		if (rb_fd_isset(fptr->fd, &fds[2])) {
 		    rb_ary_push(list, rb_ary_entry(except, i));
 		}
@@ -4645,4 +4653,75 @@ rb_f_select(argc, argv, obj)
 }
 
+struct select_args {
+    VALUE read, write, except;
+    struct timeval *timeout;
+    rb_fdset_t fdsets[4];
+};
+
+#ifdef HAVE_RB_FD_INIT
+static VALUE
+select_call(arg)
+    VALUE arg;
+{
+    struct select_args *p = (struct select_args *)arg;
+
+    return select_internal(p->read, p->write, p->except, p->timeout, p->fdsets);
+}
+
+static VALUE
+select_end(arg)
+    VALUE arg;
+{
+    struct select_args *p = (struct select_args *)arg;
+    int i;
+
+    for (i = 0; i < sizeof(p->fdsets) / sizeof(p->fdsets[0]); ++i)
+	rb_fd_term(&p->fdsets[i]);
+    return Qnil;
+}
+#endif
+
+/*
+ *  call-seq:
+ *     IO.select(read_array
+ *               [, write_array
+ *               [, error_array
+ *               [, timeout]]] ) =>  array  or  nil
+ *
+ *  See <code>Kernel#select</code>.
+ */
+
+static VALUE
+rb_f_select(argc, argv, obj)
+    int argc;
+    VALUE *argv;
+    VALUE obj;
+{
+    VALUE timeout;
+    struct select_args args;
+    struct timeval timerec;
+    int i;
+
+    rb_scan_args(argc, argv, "13", &args.read, &args.write, &args.except, &timeout);
+    if (NIL_P(timeout)) {
+	args.timeout = 0;
+    }
+    else {
+	timerec = rb_time_interval(timeout);
+	args.timeout = &timerec;
+    }
+
+    for (i = 0; i < sizeof(args.fdsets) / sizeof(args.fdsets[0]); ++i)
+	rb_fd_init(&args.fdsets[i]);
+
+#ifdef HAVE_RB_FD_INIT
+    return rb_ensure(select_call, (VALUE)&args, select_end, (VALUE)&args);
+#else
+    return select_internal(args.read, args.write, args.except,
+			   args.timeout, args.fdsets);
+#endif
+
+}
+
 #if !defined(MSDOS) && !defined(__human68k__)
 static int
Index: ext/io/wait/wait.c
===================================================================
RCS file: /cvs/ruby/src/ruby/ext/io/wait/wait.c,v
retrieving revision 1.4
diff -U2 -p -r1.4 wait.c
--- ext/io/wait/wait.c	6 Dec 2004 08:40:28 -0000	1.4
+++ ext/io/wait/wait.c	31 May 2005 06:47:23 -0000
@@ -51,4 +51,22 @@ io_ready_p(io)
 }
 
+struct wait_readable_arg {
+    rb_fdset_t fds;
+    struct timeval *timeout;
+};
+
+#ifdef HAVE_RB_FD_INIT
+static VALUE
+wait_readable(p)
+    VALUE p;
+{
+    struct wait_readable_arg *arg = (struct wait_readable_arg *)p;
+    rb_fdset_t *fds = &arg->fds;
+
+    return (VALUE)rb_thread_select(rb_fd_max(fds), rb_fd_ptr(fds), NULL, NULL, arg->timeout);
+}
+#endif
+
+
 /*
 =begin
@@ -65,8 +83,8 @@ io_wait(argc, argv, io)
 {
     OpenFile *fptr;
-    fd_set rd;
+    struct wait_readable_arg arg;
     int fd, n;
     VALUE timeout;
-    struct timeval *tp, timerec;
+    struct timeval timerec;
 
     GetOpenFile(io, fptr);
@@ -74,16 +92,22 @@ io_wait(argc, argv, io)
     rb_scan_args(argc, argv, "01", &timeout);
     if (NIL_P(timeout)) {
-	tp = 0;
+	arg.timeout = 0;
     }
     else {
 	timerec = rb_time_interval(timeout);
-	tp = &timerec;
+	arg.timeout = &timerec;
     }
 
     if (rb_io_read_pending(fptr)) return Qtrue;
     fd = fptr->fd;
-    FD_ZERO(&rd);
-    FD_SET(fd, &rd);
-    if (rb_thread_select(fd + 1, &rd, NULL, NULL, tp) < 0)
+    rb_fd_init(&arg.fds);
+    rb_fd_set(fd, &arg.fds);
+#ifdef HAVE_RB_FD_INIT
+    n = (int)rb_ensure(wait_readable, (VALUE)&arg,
+		       (VALUE (*)_((VALUE)))rb_fd_term, (VALUE)&arg.fds);
+#else
+    n = rb_thread_select(fd + 1, rb_fd_ptr(&rd), NULL, NULL, tp)
+#endif
+    if (n < 0)
 	rb_sys_fail(0);
     rb_io_check_closed(fptr);
Index: ext/socket/socket.c
===================================================================
RCS file: /cvs/ruby/src/ruby/ext/socket/socket.c,v
retrieving revision 1.144
diff -U2 -p -r1.144 socket.c
--- ext/socket/socket.c	9 Mar 2005 09:29:51 -0000	1.144
+++ ext/socket/socket.c	31 May 2005 07:02:27 -0000
@@ -889,24 +889,23 @@ ruby_socket(domain, type, proto)
 
 static int
-wait_connectable(fd)
+wait_connectable0(fd, fds)
     int fd;
+    rb_fdset_t *fds;
 {
     int sockerr, sockerrlen;
-    fd_set fds_w;
-    fd_set fds_e;
 
     for (;;) {
-	FD_ZERO(&fds_w);
-	FD_ZERO(&fds_e);
+	rb_fd_zero(&fds[0]);
+	rb_fd_zero(&fds[1]);
 
-	FD_SET(fd, &fds_w);
-	FD_SET(fd, &fds_e);
+	rb_fd_set(fd, &fds[0]);
+	rb_fd_set(fd, &fds[1]);
 
-	rb_thread_select(fd+1, 0, &fds_w, &fds_e, 0);
+	rb_thread_select(fd+1, 0, rb_fd_ptr(&fds[0]), rb_fd_ptr(&fds[1]), 0);
 
-	if (FD_ISSET(fd, &fds_w)) {
+	if (rb_fd_isset(fd, &fds[0])) {
 	    return 0;
 	}
-	else if (FD_ISSET(fd, &fds_e)) {
+	else if (rb_fd_isset(fd, &fds[1])) {
 	    sockerrlen = sizeof(sockerr);
 	    if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&sockerr,
@@ -923,4 +922,46 @@ wait_connectable(fd)
 }
 
+struct wait_connectable_arg {
+    int fd;
+    rb_fdset_t *fds;
+};
+
+#ifdef HAVE_RB_FD_INIT
+static VALUE
+try_wait_connectable(arg)
+    VALUE arg;
+{
+    struct wait_connectable_arg *p = (struct wait_connectable_arg *)arg;
+    return (VALUE)wait_connectable0(p->fd, p->fds);
+}
+
+static VALUE
+wait_connectable_ensure(arg)
+    VALUE arg;
+{
+    struct wait_connectable_arg *p = (struct wait_connectable_arg *)arg;
+    rb_fd_term(&p->fds[0]);
+    rb_fd_term(&p->fds[1]);
+    return Qnil;
+}
+#endif
+
+static int
+wait_connectable(fd)
+    int fd;
+{
+    struct wait_connectable_arg arg;
+
+    rb_fd_init(&arg.fds[0]);
+    rb_fd_init(&arg.fds[1]);
+#ifdef HAVE_RB_FD_INIT
+    arg.fd = fd;
+    return (int)rb_ensure(try_wait_connectable, (VALUE)&arg,
+			  wait_connectable_ensure,(VALUE)&arg);
+#else
+    return wait_connectable0(fd, arg.fds);
+#endif
+}
+
 #ifdef __CYGWIN__
 #define WAIT_IN_PROGRESS 10
@@ -1740,9 +1781,9 @@ thread_read_select(fd)
     int fd;
 {
-    fd_set fds;
+    rb_fdset_t fds;
 
-    FD_ZERO(&fds);
-    FD_SET(fd, &fds);
-    rb_thread_select(fd+1, &fds, 0, 0, 0);
+    rb_fd_init(&fds);
+    rb_fd_set(fd, &fds);
+    rb_thread_select(fd+1, rb_fd_ptr(&fds), 0, 0, 0);
 }
 #endif


-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦

In This Thread