1 | //===-- Implementation of atexit ------------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "src/stdlib/atexit.h" |
10 | #include "hdr/types/atexithandler_t.h" |
11 | #include "src/__support/common.h" |
12 | #include "src/__support/macros/config.h" |
13 | #include "src/stdlib/exit_handler.h" |
14 | |
15 | namespace LIBC_NAMESPACE_DECL { |
16 | |
17 | constinit ExitCallbackList atexit_callbacks; |
18 | Mutex handler_list_mtx(false, false, false, false); |
19 | [[gnu::weak]] extern void teardown_main_tls(); |
20 | |
21 | extern "C" { |
22 | |
23 | int __cxa_atexit(AtExitCallback *callback, void *payload, void *) { |
24 | return add_atexit_unit(atexit_callbacks, {callback, payload}); |
25 | } |
26 | |
27 | void __cxa_finalize(void *dso) { |
28 | if (!dso) { |
29 | call_exit_callbacks(atexit_callbacks); |
30 | if (teardown_main_tls) |
31 | teardown_main_tls(); |
32 | } |
33 | } |
34 | |
35 | } // extern "C" |
36 | |
37 | LLVM_LIBC_FUNCTION(int, atexit, (__atexithandler_t callback)) { |
38 | return add_atexit_unit( |
39 | atexit_callbacks, |
40 | {&stdc_at_exit_func, reinterpret_cast<void *>(callback)}); |
41 | } |
42 | |
43 | } // namespace LIBC_NAMESPACE_DECL |
44 | |