From 4e9438bc9153f7a1f4ea0af85c8dbe359e1a55d8 Mon Sep 17 00:00:00 2001 From: kosaki Date: Tue, 30 Aug 2011 00:53:44 +0000 Subject: * backport r33117 from trunk. * thread.c (rb_thread_select): rewrite by using rb_thread_fd_select(). old one is EINTR unsafe. Patch by Eric Wong. [Bug #5229] [ruby-core:39102] * test/-ext-/old_thread_select/test_old_thread_select.rb: a testcase for rb_thread_select(). * ext/-test-/old_thread_select/old_thread_select.c: ditto. * ext/-test-/old_thread_select/depend: ditto. * ext/-test-/old_thread_select/extconf.rb: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_9_3@33119 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- thread.c | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-) (limited to 'thread.c') diff --git a/thread.c b/thread.c index 56077d83c5..f14cba7d12 100644 --- a/thread.c +++ b/thread.c @@ -2682,29 +2682,36 @@ int rb_thread_select(int max, fd_set * read, fd_set * write, fd_set * except, struct timeval *timeout) { - if (!read && !write && !except) { - if (!timeout) { - rb_thread_sleep_forever(); - return 0; - } - rb_thread_wait_for(*timeout); - return 0; + rb_fdset_t fdsets[3] = { 0 }; + rb_fdset_t *rfds = NULL; + rb_fdset_t *wfds = NULL; + rb_fdset_t *efds = NULL; + int retval; + + if (read) { + rfds = &fdsets[0]; + rb_fd_copy(rfds, read, max); + } + if (write) { + wfds = &fdsets[1]; + rb_fd_copy(wfds, write, max); + } + if (except) { + efds = &fdsets[2]; + rb_fd_copy(efds, except, max); } - else { - int lerrno = errno; - int result; - BLOCKING_REGION({ - result = select(max, read, write, except, timeout); - if (result < 0) - lerrno = errno; - }, ubf_select, GET_THREAD()); - errno = lerrno; + retval = rb_thread_fd_select(max, rfds, efds, wfds, timeout); - return result; - } -} + if (rfds) + rb_fd_term(rfds); + if (wfds) + rb_fd_term(wfds); + if (efds) + rb_fd_term(efds); + return retval; +} int rb_thread_fd_select(int max, rb_fdset_t * read, rb_fdset_t * write, rb_fdset_t * except, -- cgit v1.2.3