From 2f248f91ee72fc0cdbe0ca50ea1a3116cf11e8ca Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Wed, 6 Mar 2024 13:29:10 -0500 Subject: [PATCH] Fix Ruby 3.4-dev compatibility --- CHANGELOG.md | 2 ++ Gemfile.lock | 3 +-- ext/pitchfork_http/epollexclusive.h | 22 +++++++++++++++------- ext/pitchfork_http/extconf.rb | 2 ++ 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f5705f5..b476b78f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Unreleased +- Fix Ruby 3.4-dev compatibility. + # 0.11.0 - Drop invalid response headers. diff --git a/Gemfile.lock b/Gemfile.lock index 1740894d..3a71cf2e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -20,8 +20,7 @@ GEM PLATFORMS aarch64-linux - arm64-darwin-21 - arm64-darwin-22 + arm64-darwin x86_64-linux DEPENDENCIES diff --git a/ext/pitchfork_http/epollexclusive.h b/ext/pitchfork_http/epollexclusive.h index cc051ac4..c38404b6 100644 --- a/ext/pitchfork_http/epollexclusive.h +++ b/ext/pitchfork_http/epollexclusive.h @@ -21,6 +21,16 @@ # 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: @@ -54,8 +64,7 @@ static VALUE prep_readers(VALUE cls, VALUE readers) */ 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; @@ -65,7 +74,7 @@ static VALUE prep_readers(VALUE cls, VALUE readers) #if USE_EPOLL struct ep_wait { struct epoll_event event; - rb_io_t *fptr; + VALUE io; int timeout_msec; }; @@ -79,7 +88,7 @@ static void *do_wait(void *ptr) /* runs w/o GVL */ * 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); } @@ -93,11 +102,10 @@ get_readers(VALUE epio, VALUE ready, VALUE readers, VALUE timeout_msec) 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 */ diff --git a/ext/pitchfork_http/extconf.rb b/ext/pitchfork_http/extconf.rb index 939cfe4b..5ed2b562 100644 --- a/ext/pitchfork_http/extconf.rb +++ b/ext/pitchfork_http/extconf.rb @@ -3,6 +3,8 @@ have_const("PR_SET_CHILD_SUBREAPER", "sys/prctl.h") have_func("rb_enc_interned_str", "ruby.h") # Ruby 3.0+ +have_func("rb_io_descriptor", "ruby.h") # Ruby 3.1+ + if RUBY_VERSION.start_with?('3.0.') # https://bugs.ruby-lang.org/issues/18772 $CFLAGS << ' -DRB_ENC_INTERNED_STR_NULL_CHECK=1 '