ext/pitchfork_http/epollexclusive.h in pitchfork-0.11.0 vs ext/pitchfork_http/epollexclusive.h in pitchfork-0.11.1

- old
+ new

@@ -19,10 +19,20 @@ # define USE_EPOLL (1) #else # define USE_EPOLL (0) #endif +#ifndef HAVE_RB_IO_DESCRIPTOR /* Ruby < 3.1 */ +static int rb_io_descriptor(VALUE io) +{ + rb_io_t *fptr; + GetOpenFile(io, fptr); + rb_io_check_closed(fptr); + return fptr->fd; +} +#endif + #if USE_EPOLL /* * :nodoc: * returns IO object if EPOLLEXCLUSIVE works and arms readers */ @@ -52,22 +62,21 @@ * code path for doing it). So let the kernel spend * cycles on maintaining level-triggering. */ e.events = EPOLLEXCLUSIVE | EPOLLIN; io = rb_io_get_io(io); - GetOpenFile(io, fptr); - rc = epoll_ctl(epfd, EPOLL_CTL_ADD, fptr->fd, &e); + rc = epoll_ctl(epfd, EPOLL_CTL_ADD, rb_io_descriptor(io), &e); if (rc < 0) rb_sys_fail("epoll_ctl"); } return epio; } #endif /* USE_EPOLL */ #if USE_EPOLL struct ep_wait { struct epoll_event event; - rb_io_t *fptr; + VALUE io; int timeout_msec; }; static void *do_wait(void *ptr) /* runs w/o GVL */ { @@ -77,11 +86,11 @@ * Linux delivers epoll events in the order received, and using * maxevents=1 ensures we pluck one item off ep->rdllist * at-a-time (c.f. fs/eventpoll.c in linux.git, it's quite * easy-to-understand for anybody familiar with Ruby C). */ - return (void *)(long)epoll_wait(epw->fptr->fd, &epw->event, 1, + return (void *)(long)epoll_wait(rb_io_descriptor(epw->io), &epw->event, 1, epw->timeout_msec); } /* :nodoc: */ /* readers must not change between prepare_readers and get_readers */ @@ -91,14 +100,13 @@ struct ep_wait epw; long n; Check_Type(ready, T_ARRAY); Check_Type(readers, T_ARRAY); - epio = rb_io_get_io(epio); - GetOpenFile(epio, epw.fptr); - + epw.io = rb_io_get_io(epio); epw.timeout_msec = NUM2INT(timeout_msec); n = (long)rb_thread_call_without_gvl(do_wait, &epw, RUBY_UBF_IO, NULL); + RB_GC_GUARD(epw.io); if (n < 0) { if (errno != EINTR) rb_sys_fail("epoll_wait"); } else if (n > 0) { /* maxevents is hardcoded to 1 */ VALUE obj = rb_ary_entry(readers, epw.event.data.u64);