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.