From e599c3d018439b91aa67d9da2fb9dfab4c34baeb Mon Sep 17 00:00:00 2001 From: Randy Stauner Date: Tue, 5 Aug 2025 14:55:31 -0700 Subject: [PATCH 1/2] Ruby: Mark credential object in channel The credentials object potentially holds a reference to a proc when composed with CallCredentials. We need the proc to live so that when requests build the credentials the proc can still be invoked. For the proc to live we need the credentials object to live so it needs to be marked by the channel. Co-authored-by: Ufuk Kayserilioglu Co-authored-by: Peter Zhu Co-authored-by: Kevin Menard --- src/ruby/ext/grpc/rb_channel.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/ruby/ext/grpc/rb_channel.c b/src/ruby/ext/grpc/rb_channel.c index d161e9c4b0c6a..778cf01a8e42d 100644 --- a/src/ruby/ext/grpc/rb_channel.c +++ b/src/ruby/ext/grpc/rb_channel.c @@ -62,6 +62,7 @@ static VALUE grpc_rb_cChannelArgs; /* grpc_rb_channel wraps a grpc_channel. */ typedef struct grpc_rb_channel { grpc_channel* channel; + VALUE mark; } grpc_rb_channel; static void grpc_rb_channel_free(void* p) { @@ -76,9 +77,13 @@ static void grpc_rb_channel_free(void* p) { xfree(p); } +static void grpc_rb_channel_mark(void *p) { + rb_gc_mark(((grpc_rb_channel *)p)->mark); +} + static rb_data_type_t grpc_channel_data_type = { "grpc_channel", - {NULL, grpc_rb_channel_free, GRPC_RB_MEMSIZE_UNAVAILABLE, {NULL, NULL}}, + {grpc_rb_channel_mark, grpc_rb_channel_free, GRPC_RB_MEMSIZE_UNAVAILABLE, {NULL, NULL}}, NULL, NULL, #ifdef RUBY_TYPED_FREE_IMMEDIATELY @@ -91,6 +96,7 @@ static VALUE grpc_rb_channel_alloc(VALUE cls) { grpc_ruby_init(); grpc_rb_channel* wrapper = ALLOC(grpc_rb_channel); wrapper->channel = NULL; + wrapper->mark = Qnil; return TypedData_Wrap_Struct(cls, &grpc_channel_data_type, wrapper); } @@ -139,6 +145,7 @@ static VALUE grpc_rb_channel_init(int argc, VALUE* argv, VALUE self) { return Qnil; } wrapper->channel = grpc_channel_create(target_chars, creds, &channel_args); + wrapper->mark = rb_credentials; } grpc_rb_channel_args_destroy(&channel_args); if (wrapper->channel == NULL) { From 120de4dae0c70a45f248a1979b8d5b8f1be9a481 Mon Sep 17 00:00:00 2001 From: rwstauner <142719+rwstauner@users.noreply.github.com> Date: Tue, 5 Aug 2025 22:17:11 +0000 Subject: [PATCH 2/2] Automated change: Fix sanity tests --- src/ruby/ext/grpc/rb_channel.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/ruby/ext/grpc/rb_channel.c b/src/ruby/ext/grpc/rb_channel.c index 778cf01a8e42d..34a02741e3798 100644 --- a/src/ruby/ext/grpc/rb_channel.c +++ b/src/ruby/ext/grpc/rb_channel.c @@ -77,17 +77,19 @@ static void grpc_rb_channel_free(void* p) { xfree(p); } -static void grpc_rb_channel_mark(void *p) { - rb_gc_mark(((grpc_rb_channel *)p)->mark); +static void grpc_rb_channel_mark(void* p) { + rb_gc_mark(((grpc_rb_channel*)p)->mark); } -static rb_data_type_t grpc_channel_data_type = { - "grpc_channel", - {grpc_rb_channel_mark, grpc_rb_channel_free, GRPC_RB_MEMSIZE_UNAVAILABLE, {NULL, NULL}}, - NULL, - NULL, +static rb_data_type_t grpc_channel_data_type = {"grpc_channel", + {grpc_rb_channel_mark, + grpc_rb_channel_free, + GRPC_RB_MEMSIZE_UNAVAILABLE, + {NULL, NULL}}, + NULL, + NULL, #ifdef RUBY_TYPED_FREE_IMMEDIATELY - RUBY_TYPED_FREE_IMMEDIATELY + RUBY_TYPED_FREE_IMMEDIATELY #endif };