git: 8d801641a398 - stable/14 - exit(3): make it thread-safe
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 21 Aug 2024 10:33:22 UTC
The branch stable/14 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=8d801641a39834cf8ce72dc88cf8bc5712cc1cad commit 8d801641a39834cf8ce72dc88cf8bc5712cc1cad Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2024-07-24 20:41:32 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2024-08-21 10:32:49 +0000 exit(3): make it thread-safe (cherry picked from commit 3f3ec4b99f79d32a0bf15495559ca9883bd751f2) --- lib/libc/stdlib/exit.3 | 20 ++++++++++++++++++-- lib/libc/stdlib/exit.c | 21 +++++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/lib/libc/stdlib/exit.3 b/lib/libc/stdlib/exit.3 index afdc58ec4831..c190f5fac27f 100644 --- a/lib/libc/stdlib/exit.3 +++ b/lib/libc/stdlib/exit.3 @@ -29,9 +29,8 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)exit.3 8.1 (Berkeley) 6/4/93 .\" -.Dd August 5, 2021 +.Dd July 24, 2024 .Dt EXIT 3 .Os .Sh NAME @@ -104,6 +103,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 a0c9622944c5..b2c2fa7db4bb 100644 --- a/lib/libc/stdlib/exit.c +++ b/lib/libc/stdlib/exit.c @@ -34,6 +34,7 @@ static char sccsid[] = "@(#)exit.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include "namespace.h" #include <stdlib.h> +#include <pthread.h> #include <unistd.h> #include "un-namespace.h" @@ -51,6 +52,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. */ @@ -62,6 +77,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.