aboutsummaryrefslogtreecommitdiff
path: root/stdlib/exit.c
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib/exit.c')
-rw-r--r--stdlib/exit.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/stdlib/exit.c b/stdlib/exit.c
index 5166c78044..bbaf138806 100644
--- a/stdlib/exit.c
+++ b/stdlib/exit.c
@@ -132,9 +132,17 @@ __run_exit_handlers (int status, struct exit_function_list **listp,
}
+/* The lock handles concurrent exit(), even though the C/POSIX standard states
+ that calling exit() more than once is UB. The recursive lock allows
+ atexit() handlers or destructors to call exit() itself. In this case, the
+ handler list execution will resume at the point of the current handler. */
+__libc_lock_define_initialized_recursive (static, __exit_lock)
+
void
exit (int status)
{
+ /* The exit should never return, so there is no need to unlock it. */
+ __libc_lock_lock_recursive (__exit_lock);
__run_exit_handlers (status, &__exit_funcs, true, true);
}
libc_hidden_def (exit)