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).
This commit is contained in:
parent
47ff4a1658
commit
41dd15944f
65
thread.c
65
thread.c
@ -4342,7 +4342,11 @@ rb_thread_fd_select(int max, rb_fdset_t * read, rb_fdset_t * write, rb_fdset_t *
|
|||||||
int
|
int
|
||||||
rb_thread_wait_for_single_fd(int fd, int events, struct timeval *timeout)
|
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;
|
int result = 0;
|
||||||
nfds_t nfds;
|
nfds_t nfds;
|
||||||
struct waiting_fd wfd;
|
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);
|
thread_io_setup_wfd(th, fd, &wfd);
|
||||||
|
|
||||||
EC_PUSH_TAG(wfd.th->ec);
|
if (timeout == NULL && thread_io_wait_events(th, fd, events, NULL)) {
|
||||||
if ((state = EC_EXEC_TAG()) == TAG_NONE) {
|
// fd is readable
|
||||||
rb_hrtime_t *to, rel, end = 0;
|
state = 0;
|
||||||
struct timeval tv;
|
fds[0].revents = events;
|
||||||
|
errno = 0;
|
||||||
RUBY_VM_CHECK_INTS_BLOCKING(wfd.th->ec);
|
}
|
||||||
|
else {
|
||||||
timeout_prepare(&to, &rel, &end, timeout);
|
EC_PUSH_TAG(wfd.th->ec);
|
||||||
fds[0].fd = fd;
|
if ((state = EC_EXEC_TAG()) == TAG_NONE) {
|
||||||
fds[0].events = (short)events;
|
rb_hrtime_t *to, rel, end = 0;
|
||||||
fds[0].revents = 0;
|
RUBY_VM_CHECK_INTS_BLOCKING(wfd.th->ec);
|
||||||
|
timeout_prepare(&to, &rel, &end, timeout);
|
||||||
do {
|
do {
|
||||||
nfds = 1;
|
nfds = 1;
|
||||||
|
|
||||||
lerrno = 0;
|
lerrno = 0;
|
||||||
BLOCKING_REGION(wfd.th, {
|
BLOCKING_REGION(wfd.th, {
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
|
|
||||||
if (!RUBY_VM_INTERRUPTED(wfd.th->ec)) {
|
if (!RUBY_VM_INTERRUPTED(wfd.th->ec)) {
|
||||||
result = ppoll(fds, nfds, rb_hrtime2timespec(&ts, to), 0);
|
result = ppoll(fds, nfds, rb_hrtime2timespec(&ts, to), 0);
|
||||||
if (result < 0) lerrno = errno;
|
if (result < 0) lerrno = errno;
|
||||||
}
|
}
|
||||||
}, ubf_select, wfd.th, TRUE);
|
}, ubf_select, wfd.th, TRUE);
|
||||||
|
|
||||||
RUBY_VM_CHECK_INTS_BLOCKING(wfd.th->ec);
|
RUBY_VM_CHECK_INTS_BLOCKING(wfd.th->ec);
|
||||||
} while (wait_retryable(&result, lerrno, to, end) &&
|
} while (wait_retryable(&result, lerrno, to, end));
|
||||||
thread_io_wait_events(th, fd, events, rb_hrtime2timeval(&tv, to)) &&
|
}
|
||||||
wait_retryable(&result, lerrno, to, end));
|
EC_POP_TAG();
|
||||||
}
|
}
|
||||||
EC_POP_TAG();
|
|
||||||
|
|
||||||
thread_io_wake_pending_closer(&wfd);
|
thread_io_wake_pending_closer(&wfd);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user