diff options
author | Rickard Green <[email protected]> | 2011-11-11 19:18:36 +0100 |
---|---|---|
committer | Rickard Green <[email protected]> | 2011-11-13 20:40:59 +0100 |
commit | 6214fde94809079d1764e4273886544272784eb3 (patch) | |
tree | 9fde50efb1f6bd618314ac7e42e304cf78326978 | |
parent | 15774d2ac5ba38dba287309f91eb7e4f58b9a636 (diff) | |
download | otp-6214fde94809079d1764e4273886544272784eb3.tar.gz otp-6214fde94809079d1764e4273886544272784eb3.tar.bz2 otp-6214fde94809079d1764e4273886544272784eb3.zip |
Make sure only one thread exits the runtime system
The runtime system crashed if more than one thread tried to exit
the runtime system at the same time.
-rw-r--r-- | erts/emulator/beam/erl_init.c | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c index 98b997583c..05fa10964a 100644 --- a/erts/emulator/beam/erl_init.c +++ b/erts/emulator/beam/erl_init.c @@ -71,6 +71,8 @@ static void erl_init(int ncpu); #define ERTS_MIN_COMPAT_REL 7 +static erts_atomic_t exiting; + #ifdef ERTS_SMP erts_smp_atomic32_t erts_writing_erl_crash_dump; erts_tsd_key_t erts_is_crash_dumping_key; @@ -644,6 +646,7 @@ early_init(int *argc, char **argv) /* erts_use_r9_pids_ports = 0; erts_sys_pre_init(); + erts_atomic_init_nob(&exiting, 0); #ifdef ERTS_SMP erts_thr_progress_pre_init(); #endif @@ -1502,6 +1505,29 @@ __decl_noreturn void erts_thr_fatal_error(int err, char *what) static void system_cleanup(int exit_code) { + /* + * Make sure only one thread exits the runtime system. + */ + if (erts_atomic_inc_read_nob(&exiting) != 1) { + /* + * Another thread is currently exiting the system; + * wait for it to do its job. + */ +#ifdef ERTS_SMP + if (erts_thr_progress_is_managed_thread()) { + /* + * The exiting thread might be waiting for + * us to block; need to update status... + */ + erts_thr_progress_active(NULL, 0); + erts_thr_progress_prepare_wait(NULL); + } +#endif + /* Wait forever... */ + while (1) + erts_milli_sleep(10000000); + } + /* No cleanup wanted if ... * 1. we are about to do an abnormal exit * 2. we haven't finished initializing, or @@ -1566,10 +1592,10 @@ __decl_noreturn void erl_exit0(char *file, int line, int n, char *fmt,...) va_start(args, fmt); - save_statistics(); - system_cleanup(n); + save_statistics(); + an = abs(n); if (erts_mtrace_enabled) @@ -1606,10 +1632,10 @@ __decl_noreturn void erl_exit(int n, char *fmt,...) va_start(args, fmt); - save_statistics(); - system_cleanup(n); + save_statistics(); + an = abs(n); if (erts_mtrace_enabled) |