diff options
| author | Max Mouratov <mmouratov@gmail.com> | 2015-06-19 19:53:38 +0500 |
|---|---|---|
| committer | Max Mouratov <mmouratov@gmail.com> | 2017-03-17 20:50:16 +0500 |
| commit | b4db498c30aa5c752bfc6dc672ad97921d49138f (patch) | |
| tree | a1fb6e816c72c39c6dcbcc4e6f62830fdd3218fd | |
| parent | 4ac705ce49fbfca762575458e7b893d3ba0f6e80 (diff) | |
| download | ocaml-b4db498c30aa5c752bfc6dc672ad97921d49138f.tar.gz | |
runtime: allowing for repeated calls to caml_startup and caml_shutdown
| -rw-r--r-- | asmrun/startup.c | 3 | ||||
| -rw-r--r-- | byterun/caml/startup_aux.h | 4 | ||||
| -rw-r--r-- | byterun/startup.c | 7 | ||||
| -rw-r--r-- | byterun/startup_aux.c | 36 |
4 files changed, 47 insertions, 3 deletions
diff --git a/asmrun/startup.c b/asmrun/startup.c index 834e6cdda3..7abec8d11b 100644 --- a/asmrun/startup.c +++ b/asmrun/startup.c @@ -105,7 +105,8 @@ value caml_startup_exn(char **argv) char * exe_name, * proc_self_exe; char tos; - caml_stat_create_pool(); + if (!caml_startup_aux()) + return Val_unit; #ifdef WITH_SPACETIME caml_spacetime_initialize(); diff --git a/byterun/caml/startup_aux.h b/byterun/caml/startup_aux.h index 203a47d73d..80ff2e0926 100644 --- a/byterun/caml/startup_aux.h +++ b/byterun/caml/startup_aux.h @@ -33,6 +33,10 @@ extern uintnat caml_trace_level; extern void caml_parse_ocamlrunparam (void); +/* Common entry point to caml_startup. + Returns 0 if the runtime is already initialized. */ +extern int caml_startup_aux (void); + #endif /* CAML_INTERNALS */ #endif /* CAML_STARTUP_AUX_H */ diff --git a/byterun/startup.c b/byterun/startup.c index 705456492b..04032f0221 100644 --- a/byterun/startup.c +++ b/byterun/startup.c @@ -286,7 +286,8 @@ CAMLexport void caml_main(char **argv) caml_ensure_spacetime_dot_o_is_included++; - caml_stat_create_pool(); + if (!caml_startup_aux()) + return; /* Machine-dependent initialization of the floating-point hardware so that it behaves as much as possible as specified in IEEE */ @@ -407,7 +408,9 @@ CAMLexport value caml_startup_code_exn( char * cds_file; char * exe_name; - caml_stat_create_pool(); + if (!caml_startup_aux()) + return Val_unit; + caml_init_ieee_floats(); #if defined(_MSC_VER) && __STDC_SECURE_LIB__ >= 200411L caml_install_invalid_parameter_handler(); diff --git a/byterun/startup_aux.c b/byterun/startup_aux.c index 63bf7f65de..21403e3288 100644 --- a/byterun/startup_aux.c +++ b/byterun/startup_aux.c @@ -108,11 +108,47 @@ void caml_parse_ocamlrunparam(void) } } + +/* The number of outstanding calls to caml_startup */ +static int startup_count = 0; + +/* Has the runtime been shut down already? */ +static int shutdown_happened = 0; + + +int caml_startup_aux(void) +{ + if (shutdown_happened == 1) + caml_fatal_error("Fatal error: caml_startup was called after the runtime " + "was shut down with caml_shutdown"); + + /* Second and subsequent calls are ignored, + since the runtime has already started */ + startup_count++; + if (startup_count > 1) + return 0; + + caml_stat_create_pool(); + + return 1; +} + CAMLexport void caml_shutdown(void) { + if (startup_count <= 0) + caml_fatal_error("Fatal error: a call to caml_shutdown has no " + "corresponding call to caml_startup"); + + /* Do nothing unless it's the last call remaining */ + startup_count--; + if (startup_count > 0) + return; + caml_finalise_heap(); #ifndef NATIVE_CODE caml_free_shared_libs(); #endif caml_stat_destroy_pool(); + + shutdown_happened = 1; } |
