diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-07-26 13:43:38 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-07-26 13:43:38 +0000 |
commit | 6202a1fee2dd645866ad799f3dce1432864050d7 (patch) | |
tree | 94dde86ea901f22b9f542de952d48d05dbc57499 | |
parent | bd93076f1f47e8a230f2ec06f3b2d6b0b08e8a3f (diff) | |
download | ruby-6202a1fee2dd645866ad799f3dce1432864050d7.tar.gz |
gc.c: running finalizer state
* gc.c (run_finalizer): make saved running finalizer state
volatile to ensure not to be clobbered by longjmp.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55759 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | gc.c | 32 |
2 files changed, 25 insertions, 12 deletions
@@ -1,3 +1,8 @@ +Tue Jul 26 22:43:36 2016 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * gc.c (run_finalizer): make saved running finalizer state + volatile to ensure not to be clobbered by longjmp. + Tue Jul 26 19:26:00 2016 Koichi Sasada <ko1@atdot.net> * vm_insnhelper.c: introduce rb_vm_pop_frame() and use it @@ -2706,26 +2706,34 @@ run_finalizer(rb_objspace_t *objspace, VALUE obj, VALUE table) { long i; int status; - const int safe = rb_safe_level(); - const VALUE errinfo = rb_errinfo(); - const VALUE objid = nonspecial_obj_id(obj); + volatile struct { + VALUE errinfo; + VALUE objid; + long finished; + int safe; + } saved; rb_thread_t *const th = GET_THREAD(); - volatile long finished = 0; +#define RESTORE_FINALIZER() (\ + rb_set_safe_level_force(saved.safe), \ + rb_set_errinfo(saved.errinfo)) + + saved.safe = rb_safe_level(); + saved.errinfo = rb_errinfo(); + saved.objid = nonspecial_obj_id(obj); + saved.finished = 0; TH_PUSH_TAG(th); status = TH_EXEC_TAG(); if (status) { - ++finished; /* skip failed finalizer */ - rb_set_safe_level_force(safe); - rb_set_errinfo(errinfo); + ++saved.finished; /* skip failed finalizer */ } - for (i = finished; i<RARRAY_LEN(table); i++) { - finished = i; - run_single_final(RARRAY_AREF(table, i), objid); - rb_set_safe_level_force(safe); - rb_set_errinfo(errinfo); + for (i = saved.finished; + RESTORE_FINALIZER(), i<RARRAY_LEN(table); + saved.finished = ++i) { + run_single_final(RARRAY_AREF(table, i), saved.objid); } TH_POP_TAG(); +#undef RESTORE_FINALIZER } static void |