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>
This commit is contained in:
parent
13d1ded253
commit
f5d2041138
Notes:
git
2021-11-23 09:29:58 +09:00
Merged: https://github.com/ruby/ruby/pull/5156 Merged-By: XrXr
@ -58,6 +58,34 @@ pjob_call_direct(VALUE self, VALUE obj)
|
|||||||
return self;
|
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
|
void
|
||||||
Init_postponed_job(VALUE self)
|
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", pjob_register, 1);
|
||||||
rb_define_module_function(mBug, "postponed_job_register_one", pjob_register_one, 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);
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,4 +25,11 @@ class TestPostponed_job < Test::Unit::TestCase
|
|||||||
Bug.postponed_job_register_one(ary = [])
|
Bug.postponed_job_register_one(ary = [])
|
||||||
assert_equal [1], ary
|
assert_equal [1], ary
|
||||||
end
|
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
|
end
|
||||||
|
@ -1585,7 +1585,7 @@ postponed_job_register(rb_execution_context_t *ec, rb_vm_t *vm,
|
|||||||
static rb_execution_context_t *
|
static rb_execution_context_t *
|
||||||
get_valid_ec(rb_vm_t *vm)
|
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);
|
if (ec == NULL) ec = rb_vm_main_ractor_ec(vm);
|
||||||
return ec;
|
return ec;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user