From 8cf4f373ff596aaef7aaec993c355b242d4fe2c1 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Thu, 18 Dec 2025 09:35:44 +0100 Subject: [PATCH] thread_sync.c: declare queue_data_type as parent of szqueue_data_type. Allows to remove some duplicated code like szqueue_length, etc. --- include/ruby/internal/core/rtypeddata.h | 19 ++++++-- thread_sync.c | 58 ++++++++----------------- 2 files changed, 32 insertions(+), 45 deletions(-) diff --git a/include/ruby/internal/core/rtypeddata.h b/include/ruby/internal/core/rtypeddata.h index aed4bd89b8..72044562df 100644 --- a/include/ruby/internal/core/rtypeddata.h +++ b/include/ruby/internal/core/rtypeddata.h @@ -615,13 +615,24 @@ RBIMPL_ATTR_ARTIFICIAL() * directly. */ static inline void * -rbimpl_check_typeddata(VALUE obj, const rb_data_type_t *type) +rbimpl_check_typeddata(VALUE obj, const rb_data_type_t *expected_type) { - if (RB_LIKELY(RB_TYPE_P(obj, T_DATA) && RTYPEDDATA_P(obj) && RTYPEDDATA_TYPE(obj) == type)) { - return RTYPEDDATA_GET_DATA(obj); + if (RB_LIKELY(RB_TYPE_P(obj, T_DATA) && RTYPEDDATA_P(obj))) { + const rb_data_type_t *actual_type = RTYPEDDATA_TYPE(obj); + void *data = RTYPEDDATA_GET_DATA(obj); + if (RB_LIKELY(actual_type == expected_type)) { + return data; + } + + while (actual_type) { + actual_type = actual_type->parent; + if (actual_type == expected_type) { + return data; + } + } } - return rb_check_typeddata(obj, type); + return rb_check_typeddata(obj, expected_type); } diff --git a/thread_sync.c b/thread_sync.c index 962ca13d2a..d0e356b161 100644 --- a/thread_sync.c +++ b/thread_sync.c @@ -728,9 +728,14 @@ queue_memsize(const void *ptr) } static const rb_data_type_t queue_data_type = { - "queue", - {queue_mark_and_move, RUBY_TYPED_DEFAULT_FREE, queue_memsize, queue_mark_and_move}, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY|RUBY_TYPED_WB_PROTECTED + .wrap_struct_name = "Thread::Queue", + .function = { + .dmark = queue_mark_and_move, + .dfree = RUBY_TYPED_DEFAULT_FREE, + .dsize = queue_memsize, + .dcompact = queue_mark_and_move, + }, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static VALUE @@ -803,9 +808,15 @@ szqueue_memsize(const void *ptr) } static const rb_data_type_t szqueue_data_type = { - "sized_queue", - {szqueue_mark_and_move, RUBY_TYPED_DEFAULT_FREE, szqueue_memsize, szqueue_mark_and_move}, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY|RUBY_TYPED_WB_PROTECTED + .wrap_struct_name = "Thread::SizedQueue", + .function = { + .dmark = szqueue_mark_and_move, + .dfree = RUBY_TYPED_DEFAULT_FREE, + .dsize = szqueue_memsize, + .dcompact = szqueue_mark_and_move, + }, + .parent = &queue_data_type, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static VALUE @@ -1382,23 +1393,6 @@ rb_szqueue_clear(VALUE self) return self; } -/* - * Document-method: Thread::SizedQueue#length - * call-seq: - * length - * size - * - * Returns the length of the queue. - */ - -static VALUE -rb_szqueue_length(VALUE self) -{ - struct rb_szqueue *sq = szqueue_ptr(self); - - return LONG2NUM(queue_length(self, &sq->q)); -} - /* * Document-method: Thread::SizedQueue#num_waiting * @@ -1413,21 +1407,6 @@ rb_szqueue_num_waiting(VALUE self) return INT2NUM(sq->q.num_waiting + sq->num_waiting_push); } -/* - * Document-method: Thread::SizedQueue#empty? - * call-seq: empty? - * - * Returns +true+ if the queue is empty. - */ - -static VALUE -rb_szqueue_empty_p(VALUE self) -{ - struct rb_szqueue *sq = szqueue_ptr(self); - - return RBOOL(queue_length(self, &sq->q) == 0); -} - /* ConditionalVariable */ struct rb_condvar { @@ -1678,11 +1657,8 @@ Init_thread_sync(void) rb_define_method(rb_cSizedQueue, "close", rb_szqueue_close, 0); rb_define_method(rb_cSizedQueue, "max", rb_szqueue_max_get, 0); rb_define_method(rb_cSizedQueue, "max=", rb_szqueue_max_set, 1); - rb_define_method(rb_cSizedQueue, "empty?", rb_szqueue_empty_p, 0); rb_define_method(rb_cSizedQueue, "clear", rb_szqueue_clear, 0); - rb_define_method(rb_cSizedQueue, "length", rb_szqueue_length, 0); rb_define_method(rb_cSizedQueue, "num_waiting", rb_szqueue_num_waiting, 0); - rb_define_alias(rb_cSizedQueue, "size", "length"); /* CVar */ DEFINE_CLASS(ConditionVariable, Object);