From e471d2ecb8140c5b22f6925e029664e99d9ebb17 Mon Sep 17 00:00:00 2001 From: Jean byroot Boussier Date: Fri, 1 Dec 2023 03:45:07 +0100 Subject: [PATCH] Convert NIO objects to TypedData API (#310) * Convert NIO::ByteBuffer objects to TypedData API The replacement API was introduced in Ruby 1.9.2 (2010), and the old untyped data API was marked a deprecated in the documentation as of Ruby 2.3.0 (2015) Ref: https://bugs.ruby-lang.org/issues/19998 * Convert NIO::Monitor objects to TypedData API The replacement API was introduced in Ruby 1.9.2 (2010), and the old untyped data API was marked a deprecated in the documentation as of Ruby 2.3.0 (2015) Ref: https://bugs.ruby-lang.org/issues/19998 * Convert NIO::Selector objects to TypedData API The replacement API was introduced in Ruby 1.9.2 (2010), and the old untyped data API was marked a deprecated in the documentation as of Ruby 2.3.0 (2015) Ref: https://bugs.ruby-lang.org/issues/19998 --- ext/nio4r/bytebuffer.c | 74 ++++++++++++++++++++++++++---------------- ext/nio4r/monitor.c | 48 +++++++++++++++++---------- ext/nio4r/nio4r.h | 2 ++ ext/nio4r/selector.c | 61 ++++++++++++++++++++++++---------- 4 files changed, 122 insertions(+), 63 deletions(-) diff --git a/ext/nio4r/bytebuffer.c b/ext/nio4r/bytebuffer.c index cd5befb..99e34f2 100644 --- a/ext/nio4r/bytebuffer.c +++ b/ext/nio4r/bytebuffer.c @@ -8,8 +8,8 @@ static VALUE cNIO_ByteBuffer_MarkUnsetError = Qnil; /* Allocator/deallocator */ static VALUE NIO_ByteBuffer_allocate(VALUE klass); -static void NIO_ByteBuffer_gc_mark(struct NIO_ByteBuffer *byteBuffer); -static void NIO_ByteBuffer_free(struct NIO_ByteBuffer *byteBuffer); +static void NIO_ByteBuffer_free(void *data); +static size_t NIO_ByteBuffer_memsize(const void *data); /* Methods */ static VALUE NIO_ByteBuffer_initialize(VALUE self, VALUE capacity); @@ -92,28 +92,46 @@ void Init_NIO_ByteBuffer() rb_define_method(cNIO_ByteBuffer, "inspect", NIO_ByteBuffer_inspect, 0); } +static const rb_data_type_t NIO_ByteBuffer_type = { + "NIO::ByteBuffer", + { + NULL, // Nothing to mark + NIO_ByteBuffer_free, + NIO_ByteBuffer_memsize, + }, + 0, + 0, + RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED +}; + static VALUE NIO_ByteBuffer_allocate(VALUE klass) { struct NIO_ByteBuffer *bytebuffer = (struct NIO_ByteBuffer *)xmalloc(sizeof(struct NIO_ByteBuffer)); bytebuffer->buffer = NULL; - return Data_Wrap_Struct(klass, NIO_ByteBuffer_gc_mark, NIO_ByteBuffer_free, bytebuffer); + return TypedData_Wrap_Struct(klass, &NIO_ByteBuffer_type, bytebuffer); } -static void NIO_ByteBuffer_gc_mark(struct NIO_ByteBuffer *buffer) +static void NIO_ByteBuffer_free(void *data) { + struct NIO_ByteBuffer *buffer = (struct NIO_ByteBuffer *)data; + if (buffer->buffer) + xfree(buffer->buffer); + xfree(buffer); } -static void NIO_ByteBuffer_free(struct NIO_ByteBuffer *buffer) +static size_t NIO_ByteBuffer_memsize(const void *data) { + const struct NIO_ByteBuffer *buffer = (const struct NIO_ByteBuffer *)data; + size_t memsize = sizeof(struct NIO_ByteBuffer); if (buffer->buffer) - xfree(buffer->buffer); - xfree(buffer); + memsize += buffer->capacity; + return memsize; } static VALUE NIO_ByteBuffer_initialize(VALUE self, VALUE capacity) { struct NIO_ByteBuffer *buffer; - Data_Get_Struct(self, struct NIO_ByteBuffer, buffer); + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); buffer->capacity = NUM2INT(capacity); buffer->buffer = xmalloc(buffer->capacity); @@ -126,7 +144,7 @@ static VALUE NIO_ByteBuffer_initialize(VALUE self, VALUE capacity) static VALUE NIO_ByteBuffer_clear(VALUE self) { struct NIO_ByteBuffer *buffer; - Data_Get_Struct(self, struct NIO_ByteBuffer, buffer); + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); memset(buffer->buffer, 0, buffer->capacity); @@ -140,7 +158,7 @@ static VALUE NIO_ByteBuffer_clear(VALUE self) static VALUE NIO_ByteBuffer_get_position(VALUE self) { struct NIO_ByteBuffer *buffer; - Data_Get_Struct(self, struct NIO_ByteBuffer, buffer); + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); return INT2NUM(buffer->position); } @@ -149,7 +167,7 @@ static VALUE NIO_ByteBuffer_set_position(VALUE self, VALUE new_position) { int pos; struct NIO_ByteBuffer *buffer; - Data_Get_Struct(self, struct NIO_ByteBuffer, buffer); + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); pos = NUM2INT(new_position); @@ -173,7 +191,7 @@ static VALUE NIO_ByteBuffer_set_position(VALUE self, VALUE new_position) static VALUE NIO_ByteBuffer_get_limit(VALUE self) { struct NIO_ByteBuffer *buffer; - Data_Get_Struct(self, struct NIO_ByteBuffer, buffer); + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); return INT2NUM(buffer->limit); } @@ -182,7 +200,7 @@ static VALUE NIO_ByteBuffer_set_limit(VALUE self, VALUE new_limit) { int lim; struct NIO_ByteBuffer *buffer; - Data_Get_Struct(self, struct NIO_ByteBuffer, buffer); + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); lim = NUM2INT(new_limit); @@ -210,7 +228,7 @@ static VALUE NIO_ByteBuffer_set_limit(VALUE self, VALUE new_limit) static VALUE NIO_ByteBuffer_capacity(VALUE self) { struct NIO_ByteBuffer *buffer; - Data_Get_Struct(self, struct NIO_ByteBuffer, buffer); + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); return INT2NUM(buffer->capacity); } @@ -218,7 +236,7 @@ static VALUE NIO_ByteBuffer_capacity(VALUE self) static VALUE NIO_ByteBuffer_remaining(VALUE self) { struct NIO_ByteBuffer *buffer; - Data_Get_Struct(self, struct NIO_ByteBuffer, buffer); + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); return INT2NUM(buffer->limit - buffer->position); } @@ -226,7 +244,7 @@ static VALUE NIO_ByteBuffer_remaining(VALUE self) static VALUE NIO_ByteBuffer_full(VALUE self) { struct NIO_ByteBuffer *buffer; - Data_Get_Struct(self, struct NIO_ByteBuffer, buffer); + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); return buffer->position == buffer->limit ? Qtrue : Qfalse; } @@ -236,7 +254,7 @@ static VALUE NIO_ByteBuffer_get(int argc, VALUE *argv, VALUE self) int len; VALUE length, result; struct NIO_ByteBuffer *buffer; - Data_Get_Struct(self, struct NIO_ByteBuffer, buffer); + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); rb_scan_args(argc, argv, "01", &length); @@ -264,7 +282,7 @@ static VALUE NIO_ByteBuffer_fetch(VALUE self, VALUE index) { int i; struct NIO_ByteBuffer *buffer; - Data_Get_Struct(self, struct NIO_ByteBuffer, buffer); + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); i = NUM2INT(index); @@ -283,7 +301,7 @@ static VALUE NIO_ByteBuffer_put(VALUE self, VALUE string) { long length; struct NIO_ByteBuffer *buffer; - Data_Get_Struct(self, struct NIO_ByteBuffer, buffer); + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); StringValue(string); length = RSTRING_LEN(string); @@ -303,7 +321,7 @@ static VALUE NIO_ByteBuffer_read_from(VALUE self, VALUE io) struct NIO_ByteBuffer *buffer; ssize_t nbytes, bytes_read; - Data_Get_Struct(self, struct NIO_ByteBuffer, buffer); + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); io = rb_convert_type(io, T_FILE, "IO", "to_io"); io_set_nonblock(io); @@ -333,7 +351,7 @@ static VALUE NIO_ByteBuffer_write_to(VALUE self, VALUE io) struct NIO_ByteBuffer *buffer; ssize_t nbytes, bytes_written; - Data_Get_Struct(self, struct NIO_ByteBuffer, buffer); + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); io = rb_convert_type(io, T_FILE, "IO", "to_io"); io_set_nonblock(io); @@ -360,7 +378,7 @@ static VALUE NIO_ByteBuffer_write_to(VALUE self, VALUE io) static VALUE NIO_ByteBuffer_flip(VALUE self) { struct NIO_ByteBuffer *buffer; - Data_Get_Struct(self, struct NIO_ByteBuffer, buffer); + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); buffer->limit = buffer->position; buffer->position = 0; @@ -372,7 +390,7 @@ static VALUE NIO_ByteBuffer_flip(VALUE self) static VALUE NIO_ByteBuffer_rewind(VALUE self) { struct NIO_ByteBuffer *buffer; - Data_Get_Struct(self, struct NIO_ByteBuffer, buffer); + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); buffer->position = 0; buffer->mark = MARK_UNSET; @@ -383,7 +401,7 @@ static VALUE NIO_ByteBuffer_rewind(VALUE self) static VALUE NIO_ByteBuffer_mark(VALUE self) { struct NIO_ByteBuffer *buffer; - Data_Get_Struct(self, struct NIO_ByteBuffer, buffer); + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); buffer->mark = buffer->position; return self; @@ -392,7 +410,7 @@ static VALUE NIO_ByteBuffer_mark(VALUE self) static VALUE NIO_ByteBuffer_reset(VALUE self) { struct NIO_ByteBuffer *buffer; - Data_Get_Struct(self, struct NIO_ByteBuffer, buffer); + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); if (buffer->mark < 0) { rb_raise(cNIO_ByteBuffer_MarkUnsetError, "mark has not been set"); @@ -406,7 +424,7 @@ static VALUE NIO_ByteBuffer_reset(VALUE self) static VALUE NIO_ByteBuffer_compact(VALUE self) { struct NIO_ByteBuffer *buffer; - Data_Get_Struct(self, struct NIO_ByteBuffer, buffer); + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); memmove(buffer->buffer, buffer->buffer + buffer->position, buffer->limit - buffer->position); buffer->position = buffer->limit - buffer->position; @@ -419,7 +437,7 @@ static VALUE NIO_ByteBuffer_each(VALUE self) { int i; struct NIO_ByteBuffer *buffer; - Data_Get_Struct(self, struct NIO_ByteBuffer, buffer); + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); if (rb_block_given_p()) { for (i = 0; i < buffer->limit; i++) { @@ -435,7 +453,7 @@ static VALUE NIO_ByteBuffer_each(VALUE self) static VALUE NIO_ByteBuffer_inspect(VALUE self) { struct NIO_ByteBuffer *buffer; - Data_Get_Struct(self, struct NIO_ByteBuffer, buffer); + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); return rb_sprintf( "#<%s:%p @position=%d @limit=%d @capacity=%d>", diff --git a/ext/nio4r/monitor.c b/ext/nio4r/monitor.c index 41f81be..cb44d44 100644 --- a/ext/nio4r/monitor.c +++ b/ext/nio4r/monitor.c @@ -11,8 +11,8 @@ static VALUE cNIO_Monitor = Qnil; /* Allocator/deallocator */ static VALUE NIO_Monitor_allocate(VALUE klass); -static void NIO_Monitor_mark(struct NIO_Monitor *monitor); -static void NIO_Monitor_free(struct NIO_Monitor *monitor); +static void NIO_Monitor_mark(void *data); +static size_t NIO_Monitor_memsize(const void *data); /* Methods */ static VALUE NIO_Monitor_initialize(VALUE self, VALUE selector, VALUE io, VALUE interests); @@ -70,22 +70,36 @@ void Init_NIO_Monitor() rb_define_method(cNIO_Monitor, "writeable?", NIO_Monitor_is_writable, 0); } +static const rb_data_type_t NIO_Monitor_type = { + "NIO::Monitor", + { + NIO_Monitor_mark, + RUBY_TYPED_DEFAULT_FREE, + NIO_Monitor_memsize, + }, + 0, + 0, + RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED +}; + static VALUE NIO_Monitor_allocate(VALUE klass) { struct NIO_Monitor *monitor = (struct NIO_Monitor *)xmalloc(sizeof(struct NIO_Monitor)); assert(monitor); *monitor = (struct NIO_Monitor){.self = Qnil}; - return Data_Wrap_Struct(klass, NIO_Monitor_mark, NIO_Monitor_free, monitor); + return TypedData_Wrap_Struct(klass, &NIO_Monitor_type, monitor); } -static void NIO_Monitor_mark(struct NIO_Monitor *monitor) +static void NIO_Monitor_mark(void *data) { + struct NIO_Monitor *monitor = (struct NIO_Monitor *)data; rb_gc_mark(monitor->self); } -static void NIO_Monitor_free(struct NIO_Monitor *monitor) +static size_t NIO_Monitor_memsize(const void *data) { - xfree(monitor); + const struct NIO_Monitor *monitor = (const struct NIO_Monitor *)data; + return sizeof(*monitor); } static VALUE NIO_Monitor_initialize(VALUE self, VALUE io, VALUE interests, VALUE selector_obj) @@ -96,7 +110,7 @@ static VALUE NIO_Monitor_initialize(VALUE self, VALUE io, VALUE interests, VALUE interests_id = SYM2ID(interests); - Data_Get_Struct(self, struct NIO_Monitor, monitor); + TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor); if (interests_id == rb_intern("r")) { monitor->interests = EV_READ; @@ -115,9 +129,9 @@ static VALUE NIO_Monitor_initialize(VALUE self, VALUE io, VALUE interests, VALUE rb_ivar_set(self, rb_intern("interests"), interests); rb_ivar_set(self, rb_intern("selector"), selector_obj); - Data_Get_Struct(selector_obj, struct NIO_Selector, selector); + selector = NIO_Selector_unwrap(selector_obj); - monitor->self = self; + RB_OBJ_WRITE(self, &monitor->self, self); monitor->ev_io.data = (void *)monitor; /* We can safely hang onto this as we also hang onto a reference to the @@ -135,7 +149,7 @@ static VALUE NIO_Monitor_close(int argc, VALUE *argv, VALUE self) { VALUE deregister, selector; struct NIO_Monitor *monitor; - Data_Get_Struct(self, struct NIO_Monitor, monitor); + TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor); rb_scan_args(argc, argv, "01", &deregister); selector = rb_ivar_get(self, rb_intern("selector")); @@ -161,7 +175,7 @@ static VALUE NIO_Monitor_close(int argc, VALUE *argv, VALUE self) static VALUE NIO_Monitor_is_closed(VALUE self) { struct NIO_Monitor *monitor; - Data_Get_Struct(self, struct NIO_Monitor, monitor); + TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor); return monitor->selector == 0 ? Qtrue : Qfalse; } @@ -190,7 +204,7 @@ static VALUE NIO_Monitor_set_interests(VALUE self, VALUE interests) static VALUE NIO_Monitor_add_interest(VALUE self, VALUE interest) { struct NIO_Monitor *monitor; - Data_Get_Struct(self, struct NIO_Monitor, monitor); + TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor); interest = monitor->interests | NIO_Monitor_symbol2interest(interest); NIO_Monitor_update_interests(self, (int)interest); @@ -201,7 +215,7 @@ static VALUE NIO_Monitor_add_interest(VALUE self, VALUE interest) static VALUE NIO_Monitor_remove_interest(VALUE self, VALUE interest) { struct NIO_Monitor *monitor; - Data_Get_Struct(self, struct NIO_Monitor, monitor); + TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor); interest = monitor->interests & ~NIO_Monitor_symbol2interest(interest); NIO_Monitor_update_interests(self, (int)interest); @@ -227,7 +241,7 @@ static VALUE NIO_Monitor_set_value(VALUE self, VALUE obj) static VALUE NIO_Monitor_readiness(VALUE self) { struct NIO_Monitor *monitor; - Data_Get_Struct(self, struct NIO_Monitor, monitor); + TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor); if ((monitor->revents & (EV_READ | EV_WRITE)) == (EV_READ | EV_WRITE)) { return ID2SYM(rb_intern("rw")); @@ -243,7 +257,7 @@ static VALUE NIO_Monitor_readiness(VALUE self) static VALUE NIO_Monitor_is_readable(VALUE self) { struct NIO_Monitor *monitor; - Data_Get_Struct(self, struct NIO_Monitor, monitor); + TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor); if (monitor->revents & EV_READ) { return Qtrue; @@ -255,7 +269,7 @@ static VALUE NIO_Monitor_is_readable(VALUE self) static VALUE NIO_Monitor_is_writable(VALUE self) { struct NIO_Monitor *monitor; - Data_Get_Struct(self, struct NIO_Monitor, monitor); + TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor); if (monitor->revents & EV_WRITE) { return Qtrue; @@ -286,7 +300,7 @@ static void NIO_Monitor_update_interests(VALUE self, int interests) { ID interests_id; struct NIO_Monitor *monitor; - Data_Get_Struct(self, struct NIO_Monitor, monitor); + TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor); if (NIO_Monitor_is_closed(self) == Qtrue) { rb_raise(rb_eEOFError, "monitor is closed"); diff --git a/ext/nio4r/nio4r.h b/ext/nio4r/nio4r.h index 9f3148c..dc65e91 100644 --- a/ext/nio4r/nio4r.h +++ b/ext/nio4r/nio4r.h @@ -40,6 +40,8 @@ struct NIO_ByteBuffer { int position, limit, capacity, mark; }; +struct NIO_Selector *NIO_Selector_unwrap(VALUE selector); + /* Thunk between libev callbacks in NIO::Monitors and NIO::Selectors */ void NIO_Selector_monitor_callback(struct ev_loop *ev_loop, struct ev_io *io, int revents); diff --git a/ext/nio4r/selector.c b/ext/nio4r/selector.c index 517a0af..662254c 100644 --- a/ext/nio4r/selector.c +++ b/ext/nio4r/selector.c @@ -23,9 +23,10 @@ static VALUE cNIO_Selector = Qnil; /* Allocator/deallocator */ static VALUE NIO_Selector_allocate(VALUE klass); -static void NIO_Selector_mark(struct NIO_Selector *loop); +static void NIO_Selector_mark(void *data); static void NIO_Selector_shutdown(struct NIO_Selector *selector); -static void NIO_Selector_free(struct NIO_Selector *loop); +static void NIO_Selector_free(void *data); +static size_t NIO_Selector_memsize(const void *data); /* Class methods */ static VALUE NIO_Selector_supported_backends(VALUE klass); @@ -83,6 +84,18 @@ void Init_NIO_Selector(void) cNIO_Monitor = rb_define_class_under(mNIO, "Monitor", rb_cObject); } +static const rb_data_type_t NIO_Selector_type = { + "NIO::Selector", + { + NIO_Selector_mark, + NIO_Selector_free, + NIO_Selector_memsize, + }, + 0, + 0, + RUBY_TYPED_WB_PROTECTED // Don't free immediately because of shutdown +}; + /* Create the libev event loop and incoming event buffer */ static VALUE NIO_Selector_allocate(VALUE klass) { @@ -104,8 +117,7 @@ static VALUE NIO_Selector_allocate(VALUE klass) rb_sys_fail("fcntl"); } - selector = (struct NIO_Selector *)xmalloc(sizeof(struct NIO_Selector)); - + VALUE obj = TypedData_Make_Struct(klass, struct NIO_Selector, &NIO_Selector_type, selector); /* Defer initializing the loop to #initialize */ selector->ev_loop = 0; @@ -118,14 +130,21 @@ static VALUE NIO_Selector_allocate(VALUE klass) selector->wakeup.data = (void *)selector; selector->closed = selector->selecting = selector->wakeup_fired = selector->ready_count = 0; - selector->ready_array = Qnil; + RB_OBJ_WRITE(obj, &selector->ready_array, Qnil); + return obj; +} - return Data_Wrap_Struct(klass, NIO_Selector_mark, NIO_Selector_free, selector); +struct NIO_Selector *NIO_Selector_unwrap(VALUE self) +{ + struct NIO_Selector *selector; + TypedData_Get_Struct(self, struct NIO_Selector, &NIO_Selector_type, selector); + return selector; } /* NIO selectors store all Ruby objects in instance variables so mark is a stub */ -static void NIO_Selector_mark(struct NIO_Selector *selector) +static void NIO_Selector_mark(void *data) { + struct NIO_Selector *selector = (struct NIO_Selector *)data; if (selector->ready_array != Qnil) { rb_gc_mark(selector->ready_array); } @@ -151,12 +170,18 @@ static void NIO_Selector_shutdown(struct NIO_Selector *selector) } /* Ruby finalizer for selector objects */ -static void NIO_Selector_free(struct NIO_Selector *selector) +static void NIO_Selector_free(void *data) { + struct NIO_Selector *selector = (struct NIO_Selector *)data; NIO_Selector_shutdown(selector); xfree(selector); } +static size_t NIO_Selector_memsize(const void *data) +{ + return sizeof(struct NIO_Selector); +} + /* Return an array of symbols for supported backends */ static VALUE NIO_Selector_supported_backends(VALUE klass) { @@ -205,7 +230,7 @@ static VALUE NIO_Selector_initialize(int argc, VALUE *argv, VALUE self) struct NIO_Selector *selector; unsigned int flags = 0; - Data_Get_Struct(self, struct NIO_Selector, selector); + TypedData_Get_Struct(self, struct NIO_Selector, &NIO_Selector_type, selector); rb_scan_args(argc, argv, "01", &backend); @@ -259,7 +284,7 @@ static VALUE NIO_Selector_backend(VALUE self) { struct NIO_Selector *selector; - Data_Get_Struct(self, struct NIO_Selector, selector); + TypedData_Get_Struct(self, struct NIO_Selector, &NIO_Selector_type, selector); if (selector->closed) { rb_raise(rb_eIOError, "selector is closed"); } @@ -337,7 +362,7 @@ static VALUE NIO_Selector_register_synchronized(VALUE _args) io = args[1]; interests = args[2]; - Data_Get_Struct(self, struct NIO_Selector, selector); + TypedData_Get_Struct(self, struct NIO_Selector, &NIO_Selector_type, selector); if (selector->closed) { rb_raise(rb_eIOError, "selector is closed"); } @@ -418,14 +443,14 @@ static VALUE NIO_Selector_select_synchronized(VALUE _args) VALUE *args = (VALUE *)_args; - Data_Get_Struct(args[0], struct NIO_Selector, selector); + TypedData_Get_Struct(args[0], struct NIO_Selector, &NIO_Selector_type, selector); if (selector->closed) { rb_raise(rb_eIOError, "selector is closed"); } if (!rb_block_given_p()) { - selector->ready_array = rb_ary_new(); + RB_OBJ_WRITE(args[0], &selector->ready_array, rb_ary_new()); } ready = NIO_Selector_run(selector, args[1]); @@ -433,7 +458,7 @@ static VALUE NIO_Selector_select_synchronized(VALUE _args) /* Timeout */ if (ready < 0) { if (!rb_block_given_p()) { - selector->ready_array = Qnil; + RB_OBJ_WRITE(args[0], &selector->ready_array, Qnil); } return Qnil; @@ -443,7 +468,7 @@ static VALUE NIO_Selector_select_synchronized(VALUE _args) return INT2NUM(ready); } else { ready_array = selector->ready_array; - selector->ready_array = Qnil; + RB_OBJ_WRITE(args[0], &selector->ready_array, Qnil); return ready_array; } } @@ -490,7 +515,7 @@ static int NIO_Selector_run(struct NIO_Selector *selector, VALUE timeout) static VALUE NIO_Selector_wakeup(VALUE self) { struct NIO_Selector *selector; - Data_Get_Struct(self, struct NIO_Selector, selector); + TypedData_Get_Struct(self, struct NIO_Selector, &NIO_Selector_type, selector); if (selector->closed) { rb_raise(rb_eIOError, "selector is closed"); @@ -512,7 +537,7 @@ static VALUE NIO_Selector_close_synchronized(VALUE self) { struct NIO_Selector *selector; - Data_Get_Struct(self, struct NIO_Selector, selector); + TypedData_Get_Struct(self, struct NIO_Selector, &NIO_Selector_type, selector); NIO_Selector_shutdown(selector); @@ -529,7 +554,7 @@ static VALUE NIO_Selector_closed_synchronized(VALUE self) { struct NIO_Selector *selector; - Data_Get_Struct(self, struct NIO_Selector, selector); + TypedData_Get_Struct(self, struct NIO_Selector, &NIO_Selector_type, selector); return selector->closed ? Qtrue : Qfalse; }