From 9c3153e0da991e1a7df9b4cf91d6830effc79b22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3?= Date: Thu, 10 Oct 2019 11:55:43 +0900 Subject: allow rb_raise from outside of GVL Now that allocation routines like ALLOC_N() can raise exceptions on integer overflows. This is a problem when the calling thread has no GVL. Memory allocations has been allowed without it, but can still fail. Let's just relax rb_raise's restriction so that we can call it with or without GVL. With GVL the behaviour is unchanged. With no GVL, wait for it. Also, integer overflows can theoretically occur during GC when we expand the object space. We cannot do so much then. Call rb_memerror and let that routine abort the process. --- gc.c | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) (limited to 'gc.c') diff --git a/gc.c b/gc.c index f4292370a0..cc4ea12250 100644 --- a/gc.c +++ b/gc.c @@ -172,6 +172,9 @@ size_mul_or_raise(size_t x, size_t y, VALUE exc) if (LIKELY(!t.left)) { return t.right; } + else if (rb_during_gc()) { + rb_memerror(); /* or...? */ + } else { rb_raise( exc, @@ -195,6 +198,9 @@ size_mul_add_or_raise(size_t x, size_t y, size_t z, VALUE exc) if (LIKELY(!t.left)) { return t.right; } + else if (rb_during_gc()) { + rb_memerror(); /* or...? */ + } else { rb_raise( exc, @@ -219,6 +225,9 @@ size_mul_add_mul_or_raise(size_t x, size_t y, size_t z, size_t w, VALUE exc) if (LIKELY(!t.left)) { return t.right; } + else if (rb_during_gc()) { + rb_memerror(); /* or...? */ + } else { rb_raise( exc, @@ -9590,28 +9599,10 @@ objspace_reachable_objects_from_root(rb_objspace_t *objspace, void (func)(const static void objspace_xfree(rb_objspace_t *objspace, void *ptr, size_t size); -static void * -negative_size_allocation_error_with_gvl(void *ptr) -{ - rb_raise(rb_eNoMemError, "%s", (const char *)ptr); - return 0; /* should not be reached */ -} - static void negative_size_allocation_error(const char *msg) { - if (ruby_thread_has_gvl_p()) { - rb_raise(rb_eNoMemError, "%s", msg); - } - else { - if (ruby_native_thread_p()) { - rb_thread_call_with_gvl(negative_size_allocation_error_with_gvl, (void *)msg); - } - else { - fprintf(stderr, "[FATAL] %s\n", msg); - exit(EXIT_FAILURE); - } - } + rb_raise(rb_eNoMemError, "%s", msg); } static void * -- cgit v1.2.3