xref: /llvm-project/libc/src/stdlib/atexit.cpp (revision 779a444009da190c47a2f820395ca001abc29b62)
1d6698386SAlex Brachet //===-- Implementation of atexit ------------------------------------------===//
2d6698386SAlex Brachet //
3d6698386SAlex Brachet // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4d6698386SAlex Brachet // See https://llvm.org/LICENSE.txt for license information.
5d6698386SAlex Brachet // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6d6698386SAlex Brachet //
7d6698386SAlex Brachet //===----------------------------------------------------------------------===//
8d6698386SAlex Brachet 
9d6698386SAlex Brachet #include "src/stdlib/atexit.h"
1039d38d66Saaryanshukla #include "hdr/types/atexithandler_t.h"
11d6698386SAlex Brachet #include "src/__support/common.h"
125ff3ff33SPetr Hosek #include "src/__support/macros/config.h"
1339d38d66Saaryanshukla #include "src/stdlib/exit_handler.h"
14d6698386SAlex Brachet 
155ff3ff33SPetr Hosek namespace LIBC_NAMESPACE_DECL {
16d6698386SAlex Brachet 
17aac3a2a2SJoseph Huber constinit ExitCallbackList atexit_callbacks;
18aac3a2a2SJoseph Huber Mutex handler_list_mtx(false, false, false, false);
19*779a4440SSchrodinger ZHU Yifan [[gnu::weak]] extern void teardown_main_tls();
20aac3a2a2SJoseph Huber 
214318f7e5SNick Desaulniers extern "C" {
224318f7e5SNick Desaulniers 
234318f7e5SNick Desaulniers int __cxa_atexit(AtExitCallback *callback, void *payload, void *) {
2439d38d66Saaryanshukla   return add_atexit_unit(atexit_callbacks, {callback, payload});
25c6dcc359SSiva Chandra Reddy }
26c6dcc359SSiva Chandra Reddy 
274318f7e5SNick Desaulniers void __cxa_finalize(void *dso) {
28*779a4440SSchrodinger ZHU Yifan   if (!dso) {
2939d38d66Saaryanshukla     call_exit_callbacks(atexit_callbacks);
30*779a4440SSchrodinger ZHU Yifan     if (teardown_main_tls)
31*779a4440SSchrodinger ZHU Yifan       teardown_main_tls();
32*779a4440SSchrodinger ZHU Yifan   }
334318f7e5SNick Desaulniers }
344318f7e5SNick Desaulniers 
354318f7e5SNick Desaulniers } // extern "C"
364318f7e5SNick Desaulniers 
3739d38d66Saaryanshukla LLVM_LIBC_FUNCTION(int, atexit, (__atexithandler_t callback)) {
38c6dcc359SSiva Chandra Reddy   return add_atexit_unit(
3939d38d66Saaryanshukla       atexit_callbacks,
40c6dcc359SSiva Chandra Reddy       {&stdc_at_exit_func, reinterpret_cast<void *>(callback)});
41c6dcc359SSiva Chandra Reddy }
42c6dcc359SSiva Chandra Reddy 
435ff3ff33SPetr Hosek } // namespace LIBC_NAMESPACE_DECL
44