diff --git a/ChangeLog b/ChangeLog index bb37dab3de..732714c5d0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Thu Feb 24 22:51:54 2011 Nobuyoshi Nakada + + * vm.c (ruby_vm_destruct): run vm exit hooks after all objects are + destructed. + Thu Feb 24 14:40:33 2011 Shota Fukumori * ChangeLog (vim): Modeline for vim diff --git a/eval.c b/eval.c index 18ea100cc2..bbf66b3152 100644 --- a/eval.c +++ b/eval.c @@ -129,9 +129,6 @@ ruby_cleanup(volatile int ex) int nerr; void rb_threadptr_interrupt(rb_thread_t *th); void rb_threadptr_check_signal(rb_thread_t *mth); - long i; - rb_vm_t *vm = GET_VM(); - VALUE ary = (VALUE)&vm->at_exit; rb_threadptr_interrupt(th); rb_threadptr_check_signal(th); @@ -165,13 +162,6 @@ ruby_cleanup(volatile int ex) POP_TAG(); rb_thread_stop_timer_thread(); - /* at_exit functions called here; any other place more apropriate - * for this purpose? let me know if any. */ - for (i=RARRAY_LEN(ary) - 1; i>=0; i--) { - ((void(*)(rb_vm_t*))RARRAY_PTR(ary)[i])(vm); - } - rb_ary_free(ary); - #if EXIT_SUCCESS != 0 || EXIT_FAILURE != 1 switch (ex) { #if EXIT_SUCCESS != 0 diff --git a/vm.c b/vm.c index 5db91dd6ae..9528040a9e 100644 --- a/vm.c +++ b/vm.c @@ -181,6 +181,19 @@ ruby_vm_at_exit(void (*func)(rb_vm_t *)) rb_ary_push((VALUE)&GET_VM()->at_exit, (VALUE)func); } +static void +ruby_vm_run_at_exit_hooks(rb_vm_t *vm) +{ + VALUE hook = (VALUE)&vm->at_exit; + + while (RARRAY_LEN(hook) > 0) { + typedef void rb_vm_at_exit_func(rb_vm_t*); + rb_vm_at_exit_func *func = (rb_vm_at_exit_func*)rb_ary_pop(hook); + (*func)(vm); + } + rb_ary_free(hook); +} + /* Env */ /* @@ -1550,6 +1563,7 @@ ruby_vm_destruct(rb_vm_t *vm) rb_objspace_free(objspace); } #endif + ruby_vm_run_at_exit_hooks(vm); rb_vm_gvl_destroy(vm); ruby_xfree(vm); ruby_current_vm = 0;