git: 3f3ec4b99f79 - main - exit(3): make it thread-safe
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 29 Jul 2024 23:59:01 UTC
The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=3f3ec4b99f79d32a0bf15495559ca9883bd751f2 commit 3f3ec4b99f79d32a0bf15495559ca9883bd751f2 Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2024-07-24 20:41:32 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2024-07-29 23:57:34 +0000 exit(3): make it thread-safe It was explained by Rich Felker <dalias@libc.org> on libc-coord. See https://austingroupbugs.net/view.php?id=1845. Reviewed by: imp, markj Tested by: antoine (exp-run) Sponsored by: The FreeBSD Foundation MFC after: 1 month Differential revision: https://reviews.freebsd.org/D46108 --- lib/libc/stdlib/exit.3 | 19 ++++++++++++++++++- lib/libc/stdlib/exit.c | 21 +++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/lib/libc/stdlib/exit.3 b/lib/libc/stdlib/exit.3 index 1ff590bb3ae8..b117e77c9e3b 100644 --- a/lib/libc/stdlib/exit.3 +++ b/lib/libc/stdlib/exit.3 @@ -29,7 +29,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd August 5, 2021 +.Dd July 24, 2024 .Dt EXIT 3 .Os .Sh NAME @@ -102,6 +102,23 @@ values described in .Xr sysexits 3 may be used to provide more information to the parent process. .Pp +Calls to the +.Fn exit +function are serialized. +All functions registered by +.Xr atexit 3 +are executed in the first thread that called +.Nm exit . +If any other thread of the process calls +.Nm exit +before all registered functions have completed or before the process +terminates, the thread is blocked until the process terminates. +The exit status of the process is the +.Fa status +argument of the first +.Nm exit +call which thread proceeds the atexit handlers. +.Pp Note that .Fn exit does nothing to prevent bottomless recursion should a function registered diff --git a/lib/libc/stdlib/exit.c b/lib/libc/stdlib/exit.c index bca978428ce3..16631fad5b90 100644 --- a/lib/libc/stdlib/exit.c +++ b/lib/libc/stdlib/exit.c @@ -31,6 +31,7 @@ #include "namespace.h" #include <stdlib.h> +#include <pthread.h> #include <unistd.h> #include "un-namespace.h" @@ -48,6 +49,20 @@ void (*__cleanup)(void); */ int __isthreaded = 0; +static pthread_mutex_t exit_mutex; +static pthread_once_t exit_mutex_once = PTHREAD_ONCE_INIT; + +static void +exit_mutex_init_once(void) +{ + pthread_mutexattr_t ma; + + _pthread_mutexattr_init(&ma); + _pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE); + _pthread_mutex_init(&exit_mutex, &ma); + _pthread_mutexattr_destroy(&ma); +} + /* * Exit, flushing stdio buffers if necessary. */ @@ -59,6 +74,12 @@ exit(int status) _thread_autoinit_dummy_decl = 1; + /* Make exit(3) thread-safe */ + if (__isthreaded) { + _once(&exit_mutex_once, exit_mutex_init_once); + _pthread_mutex_lock(&exit_mutex); + } + /* * We're dealing with cleaning up thread_local destructors in the case of * the process termination through main() exit.