summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Wu <XrXr@users.noreply.github.com>2021-11-22 19:29:29 -0500
committerGitHub <noreply@github.com>2021-11-22 19:29:29 -0500
commitf5d20411386ff2552ff27661387ddc4bae1ebc30 (patch)
tree6e59cf9014f4f7fabb3bcb535cbaa31818b9a3ec
parent13d1ded253940585a993e92648ab9f77d355586d (diff)
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@hawthorn.email> Co-authored-by: John Crepezzi <john.crepezzi@gmail.com>
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/5156 Merged-By: XrXr
-rw-r--r--ext/-test-/postponed_job/postponed_job.c31
-rw-r--r--test/-ext-/postponed_job/test_postponed_job.rb7
-rw-r--r--vm_trace.c2
3 files changed, 39 insertions, 1 deletions
diff --git a/ext/-test-/postponed_job/postponed_job.c b/ext/-test-/postponed_job/postponed_job.c
index d8684d475a..fa57bef6f5 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)
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)
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 7dc28776d0..fee0172d11 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
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 3bc55f2c3a..66ea7b24b7 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,
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;
}