mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Avoid assert failure when NULL EC is expected
After 5680c38c75
, 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
3 changed files with 39 additions and 1 deletions
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue