From: Eric Wong <e@80x24.org>
To: sleepy-penguin@bogomips.org
Subject: [PATCH] kqueue: modernize Struct usage for Ruby 2.5.0dev
Date: Sat, 15 Apr 2017 00:25:01 +0000 [thread overview]
Message-ID: <20170415002501.19627-1-e@80x24.org> (raw)
Ruby 2.4 deprecates old macros, and it looks like 2.5.0 will
remove RSTRUCT_PTR.
---
ext/sleepy_penguin/extconf.rb | 1 +
ext/sleepy_penguin/kqueue.c | 115 ++++++++++++++++++++++++++----------------
2 files changed, 73 insertions(+), 43 deletions(-)
diff --git a/ext/sleepy_penguin/extconf.rb b/ext/sleepy_penguin/extconf.rb
index e07f5d2..f11f9c1 100644
--- a/ext/sleepy_penguin/extconf.rb
+++ b/ext/sleepy_penguin/extconf.rb
@@ -34,4 +34,5 @@ have_func('rb_thread_fd_close')
have_func('rb_update_max_fd')
have_func('rb_fd_fix_cloexec')
have_func('rb_io_get_io')
+have_func('rb_struct_size')
create_makefile('sleepy_penguin_ext')
diff --git a/ext/sleepy_penguin/kqueue.c b/ext/sleepy_penguin/kqueue.c
index d7e8d8e..e6c133f 100644
--- a/ext/sleepy_penguin/kqueue.c
+++ b/ext/sleepy_penguin/kqueue.c
@@ -18,6 +18,9 @@
#ifndef RARRAY_LENINT
# define RARRAY_LENINT(ary) (int)RARRAY_LEN(ary)
#endif
+#ifndef RARRAY_CONST_PTR
+# define RARRAY_CONST_PTR(ary) RARRAY_PTR(ary)
+#endif
#ifndef NUM2SHORT
# define NUM2SHORT(n) (short)NUM2INT(n)
#endif
@@ -233,35 +236,82 @@ static VALUE do_kevent(struct kq_per_thread *kpt)
return kevent_result(kpt, (int)nevents);
}
-static void event_set(struct kevent *event, VALUE *chg)
+#if defined(HAVE_RB_STRUCT_SIZE) && defined(RSTRUCT_GET)
+static void ev_set_struct(struct kevent *ev, VALUE event)
{
- uintptr_t ident = (uintptr_t)NUM2ULONG(chg[0]);
- short filter = NUM2SHORT(chg[1]);
- unsigned short flags = NUM2USHORT(chg[2]);
- unsigned fflags = (unsigned)NUM2UINT(chg[3]);
- intptr_t data = (intptr_t)NUM2LONG(chg[4]);
- void *udata = (void *)chg[5];
-
- EV_SET(event, ident, filter, flags, fflags, data, udata);
+ if (rb_struct_size(event) == INT2NUM(6)) {
+ uintptr_t ident = (uintptr_t)NUM2ULONG(RSTRUCT_GET(event, 0));
+ short filter = NUM2SHORT(RSTRUCT_GET(event, 1));
+ unsigned short flags = NUM2USHORT(RSTRUCT_GET(event, 2));
+ unsigned fflags = (unsigned)NUM2UINT(RSTRUCT_GET(event, 3));
+ intptr_t data = (intptr_t)NUM2LONG(RSTRUCT_GET(event, 4));
+ void *udata = (void *)RSTRUCT_GET(event, 5);
+
+ EV_SET(ev, ident, filter, flags, fflags, data, udata);
+ } else {
+ rb_raise(rb_eTypeError, "unsupported struct in changelist");
+ }
+}
+#elif RBX_STRUCT == 0 && defined(RSTRUCT_LEN) && defined(RSTRUCT_PTR)
+/* legacy MRI */
+static void ev_set_struct(struct kevent *ev, VALUE event)
+{
+ long len = RSTRUCT_LEN(*event);
+ if (len == 6) {
+ const VALUE *ptr = RSTRUCT_PTR(*event);
+ uintptr_t ident = (uintptr_t)NUM2ULONG(ptr[0]);
+ short filter = NUM2SHORT(ptr[1]);
+ unsigned short flags = NUM2USHORT(ptr[2]);
+ unsigned fflags = (unsigned)NUM2UINT(ptr[3]);
+ intptr_t data = (intptr_t)NUM2LONG(ptr[4]);
+ void *udata = (void *)ptr[5];
+
+ EV_SET(event, ident, filter, flags, fflags, data, udata);
+ } else {
+ rb_raise(rb_eTypeError, "unsupported struct in changelist");
+ }
+}
+#else
+static void ev_set_struct(struct kevent *ev, VALUE event)
+{
+ rb_raise(rb_eTypeError, "unsupported struct in changelist");
+}
+#endif
+
+static void ev_set_ary(struct kevent *ev, VALUE event)
+{
+ long len = RARRAY_LEN(event);
+ const VALUE *ptr = RARRAY_CONST_PTR(event);
+
+ if (len == 6) {
+ uintptr_t ident = (uintptr_t)NUM2ULONG(ptr[0]);
+ short filter = NUM2SHORT(ptr[1]);
+ unsigned short flags = NUM2USHORT(ptr[2]);
+ unsigned fflags = (unsigned)NUM2UINT(ptr[3]);
+ intptr_t data = (intptr_t)NUM2LONG(ptr[4]);
+ void *udata = (void *)ptr[5];
+
+ EV_SET(ev, ident, filter, flags, fflags, data, udata);
+ return;
+ }
+ rb_raise(rb_eTypeError,
+ "changelist must be an array of 6-element arrays or structs");
}
/* sets ptr and len */
-static void unpack_event(VALUE **ptr, VALUE *len, VALUE *event)
+static void unpack_event(struct kevent *ev, VALUE event)
{
- switch (TYPE(*event)) {
+ switch (TYPE(event)) {
case T_STRUCT:
if (RBX_STRUCT) {
- *event = rb_funcall(*event, rb_intern("to_a"), 0, 0);
+ event = rb_funcall(event, rb_intern("to_a"), 0, 0);
/* fall-through to T_ARRAY */
} else {
- *len = RSTRUCT_LEN(*event);
- *ptr = RSTRUCT_PTR(*event);
+ ev_set_struct(ev, event);
return;
}
case T_ARRAY:
- *len = RARRAY_LEN(*event);
- *ptr = RARRAY_PTR(*event);
- return;
+ ev_set_ary(ev, event);
default:
rb_raise(rb_eTypeError, "unsupported type in changelist");
}
@@ -269,24 +319,11 @@ static void unpack_event(VALUE **ptr, VALUE *len, VALUE *event)
static void ary2eventlist(struct kevent *events, VALUE changelist)
{
- VALUE *chg = RARRAY_PTR(changelist);
+ const VALUE *chg = RARRAY_CONST_PTR(changelist);
long i = RARRAY_LEN(changelist);
- VALUE event;
- for (; --i >= 0; chg++) {
- VALUE clen;
- VALUE *cptr;
-
- event = *chg;
- unpack_event(&cptr, &clen, &event);
- if (clen != 6)
- goto out_list;
- event_set(events++, cptr);
- }
- return;
-out_list:
- rb_raise(rb_eTypeError,
- "changelist must be an array of 6-element arrays or structs");
+ for (; --i >= 0; chg++)
+ unpack_event(events++, *chg);
}
/*
@@ -294,20 +331,12 @@ out_list:
*/
static void changelist_prepare(struct kevent *events, VALUE changelist)
{
- VALUE *cptr;
- VALUE clen;
- VALUE event;
-
switch (TYPE(changelist)) {
case T_ARRAY:
ary2eventlist(events, changelist);
return;
- case T_STRUCT:
- event = changelist;
- unpack_event(&cptr, &clen, &event);
- if (clen != 6)
- rb_raise(rb_eTypeError, "event is not a Kevent struct");
- event_set(events, cptr);
+ case T_STRUCT: /* single event */
+ unpack_event(events, changelist);
return;
default:
rb_bug("changelist_prepare not type filtered by sp_kevent");
--
EW
reply other threads:[~2017-04-15 0:25 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://yhbt.net/sleepy_penguin/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170415002501.19627-1-e@80x24.org \
--to=e@80x24.org \
--cc=sleepy-penguin@bogomips.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://yhbt.net/sleepy_penguin.git/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).