diff options
author | Koichi Sasada <ko1@atdot.net> | 2024-01-09 00:27:40 +0900 |
---|---|---|
committer | Koichi Sasada <ko1@atdot.net> | 2024-01-09 05:43:28 +0900 |
commit | 41dd15944f8843539a070a6aa1b01a71421ce4d0 (patch) | |
tree | 6c110699f8c41e290b45581aff9a668992559d1f /thread.c | |
parent | 47ff4a165802236ae951c39fda1adf2887ad75b1 (diff) |
fix `rb_thread_wait_for_single_fd` on non MN case
`rb_thread_wait_for_single_fd(fd)` waits until `fd` is ready. Without MN it shouldn't use `thread_io_wait_events()` for the retry checking (alwasy false if MN is not active).
Diffstat (limited to 'thread.c')
-rw-r--r-- | thread.c | 63 |
1 files changed, 33 insertions, 30 deletions
@@ -4342,7 +4342,11 @@ rb_thread_fd_select(int max, rb_fdset_t * read, rb_fdset_t * write, rb_fdset_t * int rb_thread_wait_for_single_fd(int fd, int events, struct timeval *timeout) { - struct pollfd fds[1]; + struct pollfd fds[1] = {{ + .fd = fd, + .events = (short)events, + .revents = 0, + }}; int result = 0; nfds_t nfds; struct waiting_fd wfd; @@ -4354,37 +4358,36 @@ rb_thread_wait_for_single_fd(int fd, int events, struct timeval *timeout) thread_io_setup_wfd(th, fd, &wfd); - EC_PUSH_TAG(wfd.th->ec); - if ((state = EC_EXEC_TAG()) == TAG_NONE) { - rb_hrtime_t *to, rel, end = 0; - struct timeval tv; - - RUBY_VM_CHECK_INTS_BLOCKING(wfd.th->ec); - - timeout_prepare(&to, &rel, &end, timeout); - fds[0].fd = fd; - fds[0].events = (short)events; - fds[0].revents = 0; - - do { - nfds = 1; - - lerrno = 0; - BLOCKING_REGION(wfd.th, { - struct timespec ts; - - if (!RUBY_VM_INTERRUPTED(wfd.th->ec)) { - result = ppoll(fds, nfds, rb_hrtime2timespec(&ts, to), 0); - if (result < 0) lerrno = errno; - } - }, ubf_select, wfd.th, TRUE); - + if (timeout == NULL && thread_io_wait_events(th, fd, events, NULL)) { + // fd is readable + state = 0; + fds[0].revents = events; + errno = 0; + } + else { + EC_PUSH_TAG(wfd.th->ec); + if ((state = EC_EXEC_TAG()) == TAG_NONE) { + rb_hrtime_t *to, rel, end = 0; RUBY_VM_CHECK_INTS_BLOCKING(wfd.th->ec); - } while (wait_retryable(&result, lerrno, to, end) && - thread_io_wait_events(th, fd, events, rb_hrtime2timeval(&tv, to)) && - wait_retryable(&result, lerrno, to, end)); + timeout_prepare(&to, &rel, &end, timeout); + do { + nfds = 1; + + lerrno = 0; + BLOCKING_REGION(wfd.th, { + struct timespec ts; + + if (!RUBY_VM_INTERRUPTED(wfd.th->ec)) { + result = ppoll(fds, nfds, rb_hrtime2timespec(&ts, to), 0); + if (result < 0) lerrno = errno; + } + }, ubf_select, wfd.th, TRUE); + + RUBY_VM_CHECK_INTS_BLOCKING(wfd.th->ec); + } while (wait_retryable(&result, lerrno, to, end)); + } + EC_POP_TAG(); } - EC_POP_TAG(); thread_io_wake_pending_closer(&wfd); |