From 64300b2c43e040ae2cd63bd0ef72a10a54db6631 Mon Sep 17 00:00:00 2001 From: take_cheeze Date: Thu, 8 May 2014 22:19:14 +0900 Subject: Add API `mrb_atexit()`. `mrb_final_mrbgems` will be called as mrb_state atexit function. Maybe useful in #1844. --- include/mruby.h | 7 +++++++ src/init.c | 8 -------- src/state.c | 23 +++++++++++++++++++++-- tasks/mrbgems.rake | 11 ++++++----- 4 files changed, 34 insertions(+), 15 deletions(-) diff --git a/include/mruby.h b/include/mruby.h index db3b06aa8..368bf1beb 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -102,6 +102,8 @@ enum gc_state { struct mrb_jmpbuf; +typedef void (*mrb_atexit_func)(struct mrb_state*); + typedef struct mrb_state { struct mrb_jmpbuf *jmp; @@ -169,6 +171,9 @@ typedef struct mrb_state { struct RClass *eStandardError_class; void *ud; /* auxiliary data */ + + mrb_atexit_func *atexit_stack; + mrb_int atexit_stack_len; } mrb_state; #if __STDC_VERSION__ >= 201112L @@ -413,6 +418,8 @@ void* mrb_pool_realloc(struct mrb_pool*, void*, size_t oldlen, size_t newlen); mrb_bool mrb_pool_can_realloc(struct mrb_pool*, void*, size_t); void* mrb_alloca(mrb_state *mrb, size_t); +void mrb_atexit(mrb_state *mrb, mrb_atexit_func func); + #ifdef MRB_DEBUG #include #define mrb_assert(p) assert(p) diff --git a/src/init.c b/src/init.c index c08c4b046..9489cea10 100644 --- a/src/init.c +++ b/src/init.c @@ -54,11 +54,3 @@ mrb_init_core(mrb_state *mrb) mrb_init_mrbgems(mrb); DONE; #endif } - -void -mrb_final_core(mrb_state *mrb) -{ -#ifndef DISABLE_GEMS - mrb_final_mrbgems(mrb); DONE; -#endif -} diff --git a/src/state.c b/src/state.c index 9dd798f92..ee03c8a38 100644 --- a/src/state.c +++ b/src/state.c @@ -14,7 +14,6 @@ void mrb_init_heap(mrb_state*); void mrb_init_core(mrb_state*); -void mrb_final_core(mrb_state*); static mrb_value inspect_main(mrb_state *mrb, mrb_value mod) @@ -40,6 +39,7 @@ mrb_open_allocf(mrb_allocf f, void *ud) mrb->ud = ud; mrb->allocf = f; mrb->current_white_part = MRB_GC_WHITE_A; + mrb->atexit_stack_len = 0; #ifndef MRB_GC_FIXED_ARENA mrb->arena = (struct RBasic**)mrb_malloc(mrb, sizeof(struct RBasic*)*MRB_GC_ARENA_SIZE); @@ -221,7 +221,11 @@ mrb_free_context(mrb_state *mrb, struct mrb_context *c) void mrb_close(mrb_state *mrb) { - mrb_final_core(mrb); + mrb_int i; + + for (i = mrb->atexit_stack_len; i > 0; --i) { + mrb->atexit_stack[i - 1](mrb); + } /* free */ mrb_gc_free_gv(mrb); @@ -258,3 +262,18 @@ mrb_top_self(mrb_state *mrb) } return mrb_obj_value(mrb->top_self); } + +void +mrb_atexit(mrb_state *mrb, mrb_atexit_func f) +{ + size_t stack_size; + + stack_size = sizeof(mrb_atexit_func) * (mrb->atexit_stack_len + 1); + if (mrb->atexit_stack_len == 0) { + mrb->atexit_stack = (mrb_atexit_func*)mrb_malloc(mrb, stack_size); + } else { + mrb->atexit_stack = (mrb_atexit_func*)mrb_realloc(mrb, mrb->atexit_stack, stack_size); + } + + mrb->atexit_stack[mrb->atexit_stack_len++] = f; +} diff --git a/tasks/mrbgems.rake b/tasks/mrbgems.rake index b57f318e0..95eddc56b 100644 --- a/tasks/mrbgems.rake +++ b/tasks/mrbgems.rake @@ -26,14 +26,15 @@ MRuby.each_target do f.puts %Q[] f.puts %Q[#{gems.map{|g| "void GENERATED_TMP_mrb_%s_gem_final(mrb_state* mrb);" % g.funcname}.join("\n")}] f.puts %Q[] - f.puts %Q[void] - f.puts %Q[mrb_init_mrbgems(mrb_state *mrb) {] - f.puts %Q[#{gems.map{|g| "GENERATED_TMP_mrb_%s_gem_init(mrb);" % g.funcname}.join("\n")}] + f.puts %Q[static void] + f.puts %Q[mrb_final_mrbgems(mrb_state *mrb) {] + f.puts %Q[#{gems.map{|g| "GENERATED_TMP_mrb_%s_gem_final(mrb);" % g.funcname}.join("\n")}] f.puts %Q[}] f.puts %Q[] f.puts %Q[void] - f.puts %Q[mrb_final_mrbgems(mrb_state *mrb) {] - f.puts %Q[#{gems.map{|g| "GENERATED_TMP_mrb_%s_gem_final(mrb);" % g.funcname}.join("\n")}] + f.puts %Q[mrb_init_mrbgems(mrb_state *mrb) {] + f.puts %Q[#{gems.map{|g| "GENERATED_TMP_mrb_%s_gem_init(mrb);" % g.funcname}.join("\n")}] + f.puts %Q[mrb_atexit(mrb, mrb_final_mrbgems);] f.puts %Q[}] end end -- cgit v1.2.3