//===-- Implementation of atexit ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "src/stdlib/atexit.h" #include "src/__support/CPP/blockstore.h" #include "src/__support/common.h" #include "src/__support/threads/mutex.h" namespace __llvm_libc { namespace { Mutex handler_list_mtx(false, false, false); using AtExitCallback = void(void); using ExitCallbackList = cpp::ReverseOrderBlockStore; constinit ExitCallbackList exit_callbacks; } // namespace namespace internal { void call_exit_callbacks() { handler_list_mtx.lock(); while (!exit_callbacks.empty()) { auto *callback = exit_callbacks.back(); exit_callbacks.pop_back(); handler_list_mtx.unlock(); callback(); handler_list_mtx.lock(); } ExitCallbackList::destroy(&exit_callbacks); } } // namespace internal LLVM_LIBC_FUNCTION(int, atexit, (AtExitCallback * callback)) { handler_list_mtx.lock(); exit_callbacks.push_back(callback); handler_list_mtx.unlock(); return 0; } } // namespace __llvm_libc