Skip to content

Commit

Permalink
Avoid assert failure when NULL EC is expected
Browse files Browse the repository at this point in the history
After 5680c38, 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.

[Bug #17573]

Co-authored-by: John Hawthorn <john@hawthorn.email>
Co-authored-by: John Crepezzi <john.crepezzi@gmail.com>
  • Loading branch information
3 people committed Nov 22, 2021
1 parent e42f994 commit b313cb6
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 1 deletion.
31 changes: 31 additions & 0 deletions ext/-test-/postponed_job/postponed_job.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,43 @@ 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)
{
VALUE mBug = rb_define_module("Bug");
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
}

7 changes: 7 additions & 0 deletions test/-ext-/postponed_job/test_postponed_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,11 @@ def test_register
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
2 changes: 1 addition & 1 deletion vm_trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down

0 comments on commit b313cb6

Please sign in to comment.