Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion box.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ static int
free_loaded_feature_index_i(st_data_t key, st_data_t value, st_data_t arg)
{
if (!FIXNUM_P(value)) {
rb_darray_free((void *)value);
rb_darray_free_sized((void *)value, long);
}
return ST_CONTINUE;
}
Expand Down
21 changes: 18 additions & 3 deletions darray.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,18 @@ rb_darray_free(void *ary)
xfree(ary);
}

void ruby_sized_xfree(void *x, size_t size);

static inline void
rb_darray_free_sized0(void *ary, size_t element_size)
{
const rb_darray_meta_t *meta = ary;
if (meta) {
ruby_sized_xfree(ary, sizeof(*meta) + (element_size * meta->capa));
}
}
#define rb_darray_free_sized(ary, T) rb_darray_free_sized0((ary), sizeof(T))

static inline void
rb_darray_free_without_gc(void *ary)
{
Expand Down Expand Up @@ -191,13 +203,16 @@ rb_darray_calloc_mul_add_without_gc(size_t x, size_t y, size_t z)
return ptr;
}

void *ruby_sized_xrealloc(void *ptr, size_t new_size, size_t old_size);

/* Internal function. Like rb_xrealloc_mul_add. */
static inline void *
rb_darray_realloc_mul_add(void *orig_ptr, size_t x, size_t y, size_t z)
rb_darray_realloc_mul_add(void *orig_ptr, size_t capa, size_t element_size, size_t header_size)
{
size_t size = rbimpl_size_add_or_raise(rbimpl_size_mul_or_raise(x, y), z);
size_t size = rbimpl_size_add_or_raise(rbimpl_size_mul_or_raise(capa, element_size), header_size);
size_t old_size = (rb_darray_capa(orig_ptr) * element_size) + header_size; // We know it won't overflow

void *ptr = xrealloc(orig_ptr, size);
void *ptr = ruby_sized_xrealloc(orig_ptr, size, old_size);
RUBY_ASSERT(ptr != NULL);

return ptr;
Expand Down
2 changes: 1 addition & 1 deletion load.c
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ loaded_features_index_clear_i(st_data_t key, st_data_t val, st_data_t arg)
{
VALUE obj = (VALUE)val;
if (!SPECIAL_CONST_P(obj)) {
rb_darray_free((void *)obj);
rb_darray_free_sized((void *)obj, long);
}
return ST_DELETE;
}
Expand Down
4 changes: 1 addition & 3 deletions symbol.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,7 @@ sym_id_entry_list_mark(void *ptr)
static void
sym_id_entry_list_free(void *ptr)
{
rb_darray(struct sym_id_entry) ary = ptr;

rb_darray_free(ary);
rb_darray_free_sized(ptr, struct sym_id_entry);
}

static size_t
Expand Down
14 changes: 14 additions & 0 deletions test/ruby/test_signal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -350,4 +350,18 @@ def test_sigwait_fd_unused
loop { sleep }
End
end if Process.respond_to?(:kill) && Process.respond_to?(:daemon)

def test_signal_during_kwarg_call
status = assert_in_out_err([], <<~'RUBY', [], [], success: false)
Thread.new do
sleep 0.1
Process.kill("TERM", $$)
end

loop do
File.open(IO::NULL, kwarg: true) {}
end
RUBY
assert_predicate(status, :signaled?) if Signal.list.include?("QUIT")
end if Process.respond_to?(:kill)
end
21 changes: 18 additions & 3 deletions thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -2737,19 +2737,27 @@ rb_threadptr_ready(rb_thread_t *th)
static VALUE
rb_threadptr_raise(rb_thread_t *target_th, int argc, VALUE *argv)
{
VALUE exc;

if (rb_threadptr_dead(target_th)) {
return Qnil;
}

VALUE exception = rb_exception_setup(argc, argv);
if (argc == 0) {
exc = rb_exc_new(rb_eRuntimeError, 0, 0);
}
else {
exc = rb_make_exception(argc, argv);
}

/* making an exception object can switch thread,
so we need to check thread deadness again */
if (rb_threadptr_dead(target_th)) {
return Qnil;
}

rb_threadptr_pending_interrupt_enque(target_th, exception);
rb_ec_setup_exception(GET_EC(), exc, Qundef);
rb_threadptr_pending_interrupt_enque(target_th, exc);
rb_threadptr_interrupt(target_th);

return Qnil;
Expand Down Expand Up @@ -2933,7 +2941,14 @@ thread_raise_m(int argc, VALUE *argv, VALUE self)
const rb_thread_t *current_th = GET_THREAD();

threadptr_check_pending_interrupt_queue(target_th);
rb_threadptr_raise(target_th, argc, argv);

if (rb_threadptr_dead(target_th)) {
return Qnil;
}

VALUE exception = rb_exception_setup(argc, argv);
rb_threadptr_pending_interrupt_enque(target_th, exception);
rb_threadptr_interrupt(target_th);

/* To perform Thread.current.raise as Kernel.raise */
if (current_th == target_th) {
Expand Down