diff options
| -rw-r--r-- | src/exit/exit.c | 14 | 
1 files changed, 14 insertions, 0 deletions
diff --git a/src/exit/exit.c b/src/exit/exit.c index a6869b37..ca11b9ad 100644 --- a/src/exit/exit.c +++ b/src/exit/exit.c @@ -1,6 +1,9 @@  #include <stdlib.h>  #include <stdint.h>  #include "libc.h" +#include "pthread_impl.h" +#include "atomic.h" +#include "syscall.h"  static void dummy()  { @@ -26,6 +29,17 @@ weak_alias(libc_exit_fini, __libc_exit_fini);  _Noreturn void exit(int code)  { +	/* Handle potentially concurrent or recursive calls to exit, +	 * whose behaviors have traditionally been undefined by the +	 * standards. Using a custom lock here avoids pulling in lock +	 * machinery and lets us trap recursive calls while supporting +	 * multiple threads contending to be the one to exit(). */ +	static volatile int exit_lock[1]; +	int tid =  __pthread_self()->tid; +	int prev = a_cas(exit_lock, 0, tid); +	if (prev == tid) a_crash(); +	else if (prev) for (;;) __syscall(SYS_pause); +  	__funcs_on_exit();  	__libc_exit_fini();  	__stdio_exit();  | 
