ruby-changes:69871
From: Alan <ko1@a...>
Date: Tue, 23 Nov 2021 09:29:56 +0900 (JST)
Subject: [ruby-changes:69871] f5d2041138 (master): Avoid assert failure when NULL EC is expected
https://git.ruby-lang.org/ruby.git/commit/?id=f5d2041138 From f5d20411386ff2552ff27661387ddc4bae1ebc30 Mon Sep 17 00:00:00 2001 From: Alan Wu <XrXr@u...> Date: Mon, 22 Nov 2021 19:29:29 -0500 Subject: Avoid assert failure when NULL EC is expected After 5680c38c75aeb5cbd219aafa8eb48c315f287d97, postponed job APIs now expect to be called on native threads not managed by Ruby and handles getting a NULL execution context. However, in debug builds the change runs into an assertion failure with GET_EC() which asserts that EC is non-NULL. Avoid the assertion failure by passing `false` for `expect_ec` instead as the intention is to handle when there is no EC. Add a test from John Crepezzi and John Hawthorn to exercise this situation. See GH-4108 See GH-5094 [Bug #17573] Co-authored-by: John Hawthorn <john@h...> Co-authored-by: John Crepezzi <john.crepezzi@g...> --- ext/-test-/postponed_job/postponed_job.c | 31 ++++++++++++++++++++++++++ test/-ext-/postponed_job/test_postponed_job.rb | 7 ++++++ vm_trace.c | 2 +- 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/ext/-test-/postponed_job/postponed_job.c b/ext/-test-/postponed_job/postponed_job.c index d8684d475a4..fa57bef6f5a 100644 --- a/ext/-test-/postponed_job/postponed_job.c +++ b/ext/-test-/postponed_job/postponed_job.c @@ -58,6 +58,34 @@ pjob_call_direct(VALUE self, VALUE obj) https://github.com/ruby/ruby/blob/trunk/ext/-test-/postponed_job/postponed_job.c#L58 return self; } +#ifdef HAVE_PTHREAD_H +#include <pthread.h> + +static void * +pjob_register_in_c_thread_i(void *obj) +{ + rb_postponed_job_register_one(0, pjob_one_callback, (void *)obj); + rb_postponed_job_register_one(0, pjob_one_callback, (void *)obj); + rb_postponed_job_register_one(0, pjob_one_callback, (void *)obj); + return NULL; +} + +static VALUE +pjob_register_in_c_thread(VALUE self, VALUE obj) +{ + pthread_t thread; + if (pthread_create(&thread, NULL, pjob_register_in_c_thread_i, (void *)obj)) { + return Qfalse; + } + + if (pthread_join(thread, NULL)) { + return Qfalse; + } + + return Qtrue; +} +#endif + void Init_postponed_job(VALUE self) { @@ -65,5 +93,8 @@ Init_postponed_job(VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/-test-/postponed_job/postponed_job.c#L93 rb_define_module_function(mBug, "postponed_job_register", pjob_register, 1); rb_define_module_function(mBug, "postponed_job_register_one", pjob_register_one, 1); rb_define_module_function(mBug, "postponed_job_call_direct", pjob_call_direct, 1); +#ifdef HAVE_PTHREAD_H + rb_define_module_function(mBug, "postponed_job_register_in_c_thread", pjob_register_in_c_thread, 1); +#endif } diff --git a/test/-ext-/postponed_job/test_postponed_job.rb b/test/-ext-/postponed_job/test_postponed_job.rb index 7dc28776d0c..fee0172d114 100644 --- a/test/-ext-/postponed_job/test_postponed_job.rb +++ b/test/-ext-/postponed_job/test_postponed_job.rb @@ -25,4 +25,11 @@ class TestPostponed_job < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/-ext-/postponed_job/test_postponed_job.rb#L25 Bug.postponed_job_register_one(ary = []) assert_equal [1], ary end + + if Bug.respond_to?(:postponed_job_register_in_c_thread) + def test_register_in_c_thread + assert Bug.postponed_job_register_in_c_thread(ary = []) + assert_equal [1], ary + end + end end diff --git a/vm_trace.c b/vm_trace.c index 3bc55f2c3ab..66ea7b24b7e 100644 --- a/vm_trace.c +++ b/vm_trace.c @@ -1585,7 +1585,7 @@ postponed_job_register(rb_execution_context_t *ec, rb_vm_t *vm, https://github.com/ruby/ruby/blob/trunk/vm_trace.c#L1585 static rb_execution_context_t * get_valid_ec(rb_vm_t *vm) { - rb_execution_context_t *ec = GET_EC(); + rb_execution_context_t *ec = rb_current_execution_context(false); if (ec == NULL) ec = rb_vm_main_ractor_ec(vm); return ec; } -- cgit v1.2.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/