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" 1019c60980SSiva Chandra Reddy #include "src/__support/CPP/blockstore.h" 11d6698386SAlex Brachet #include "src/__support/common.h" 1283b8878fSSiva Chandra Reddy #include "src/__support/threads/mutex.h" 13d6698386SAlex Brachet 14d6698386SAlex Brachet namespace __llvm_libc { 15d6698386SAlex Brachet 16d6698386SAlex Brachet namespace { 17d6698386SAlex Brachet 1883b8878fSSiva Chandra Reddy Mutex handler_list_mtx(false, false, false); 19d6698386SAlex Brachet 2019c60980SSiva Chandra Reddy using AtExitCallback = void(void); 2119c60980SSiva Chandra Reddy using ExitCallbackList = cpp::ReverseOrderBlockStore<AtExitCallback *, 32>; 2219c60980SSiva Chandra Reddy constinit ExitCallbackList exit_callbacks; 23d6698386SAlex Brachet 24d6698386SAlex Brachet } // namespace 25d6698386SAlex Brachet 26d6698386SAlex Brachet namespace internal { 27d6698386SAlex Brachet call_exit_callbacks()2819c60980SSiva Chandra Reddyvoid call_exit_callbacks() { 2983b8878fSSiva Chandra Reddy handler_list_mtx.lock(); 30ae4b59f1SAlex Brachet while (!exit_callbacks.empty()) { 31ae4b59f1SAlex Brachet auto *callback = exit_callbacks.back(); 32ae4b59f1SAlex Brachet exit_callbacks.pop_back(); 33*89aa4bd3SAlex Brachet handler_list_mtx.unlock(); 3419c60980SSiva Chandra Reddy callback(); 3583b8878fSSiva Chandra Reddy handler_list_mtx.lock(); 36d6698386SAlex Brachet } 3719c60980SSiva Chandra Reddy ExitCallbackList::destroy(&exit_callbacks); 38d6698386SAlex Brachet } 39d6698386SAlex Brachet 40d6698386SAlex Brachet } // namespace internal 41d6698386SAlex Brachet 4219c60980SSiva Chandra Reddy LLVM_LIBC_FUNCTION(int, atexit, (AtExitCallback * callback)) { 4383b8878fSSiva Chandra Reddy handler_list_mtx.lock(); 4419c60980SSiva Chandra Reddy exit_callbacks.push_back(callback); 4583b8878fSSiva Chandra Reddy handler_list_mtx.unlock(); 46d6698386SAlex Brachet return 0; 47d6698386SAlex Brachet } 48d6698386SAlex Brachet 49d6698386SAlex Brachet } // namespace __llvm_libc 50