summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authortake_cheeze <[email protected]>2014-05-08 22:19:14 +0900
committertake_cheeze <[email protected]>2014-05-08 22:19:14 +0900
commit64300b2c43e040ae2cd63bd0ef72a10a54db6631 (patch)
tree5d32debfc93c7a1511d90ca45967c7572ac5be2d
parentc071ad13a9df20e8e030320eef0a483bf4e64932 (diff)
downloadmruby-64300b2c43e040ae2cd63bd0ef72a10a54db6631.tar.gz
mruby-64300b2c43e040ae2cd63bd0ef72a10a54db6631.zip
Add API `mrb_atexit()`.
`mrb_final_mrbgems` will be called as mrb_state atexit function. Maybe useful in #1844.
-rw-r--r--include/mruby.h7
-rw-r--r--src/init.c8
-rw-r--r--src/state.c23
-rw-r--r--tasks/mrbgems.rake11
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 <assert.h>
#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