From aac3a2a291598f3aef01833927fa754c53849cdf Mon Sep 17 00:00:00 2001 From: Joseph Huber Date: Mon, 22 Jul 2024 15:28:48 -0500 Subject: [PATCH] [libc] Fix callback type in `exit_handlers.cpp` not matching (#97642) Summary: This file is an object library, but uses the `LIBC_COPT_PUBLIC_PACKAING` option. This will always be undefined which leads to a type mismatch when uses actually try to link against it. This patch simply removes this and turns it into a header only library. This means that the implementations of the callback lists and the mutexes need to live in their respective files. The result is that `atexit` needs to be defined for `at_quick_exit` to be valid. --- libc/src/stdlib/CMakeLists.txt | 15 ++++++----- libc/src/stdlib/at_quick_exit.cpp | 2 ++ libc/src/stdlib/atexit.cpp | 3 +++ libc/src/stdlib/exit_handler.cpp | 43 ------------------------------- libc/src/stdlib/exit_handler.h | 28 +++++++++++++++----- 5 files changed, 36 insertions(+), 55 deletions(-) delete mode 100644 libc/src/stdlib/exit_handler.cpp diff --git a/libc/src/stdlib/CMakeLists.txt b/libc/src/stdlib/CMakeLists.txt index 513f6ad723d564..b9b10bd2b4f716 100644 --- a/libc/src/stdlib/CMakeLists.txt +++ b/libc/src/stdlib/CMakeLists.txt @@ -51,6 +51,8 @@ add_entrypoint_object( DEPENDS libc.src.__support.OSUtil.osutil .exit_handler + .at_quick_exit + .atexit ) add_entrypoint_object( @@ -462,15 +464,11 @@ add_entrypoint_object( # TODO: Move all exit functions to linux specific -if (TARGET libc.src.__support.threads.mutex) -add_object_library( +if(TARGET libc.src.__support.threads.mutex) +add_header_library( exit_handler - SRCS - exit_handler.cpp HDRS exit_handler.h - CXX_STANDARD - 20 # For constinit DEPENDS libc.src.__support.CPP.mutex libc.src.__support.CPP.new @@ -487,6 +485,8 @@ add_entrypoint_object( atexit.cpp HDRS atexit.h + CXX_STANDARD + 20 # For constinit DEPENDS .exit_handler ) @@ -497,8 +497,11 @@ add_entrypoint_object( at_quick_exit.cpp HDRS at_quick_exit.h + CXX_STANDARD + 20 # For constinit DEPENDS .exit_handler + .atexit ) list(APPEND exit_deps diff --git a/libc/src/stdlib/at_quick_exit.cpp b/libc/src/stdlib/at_quick_exit.cpp index 7acae8c52def31..d2b4c0cec986f3 100644 --- a/libc/src/stdlib/at_quick_exit.cpp +++ b/libc/src/stdlib/at_quick_exit.cpp @@ -14,6 +14,8 @@ namespace LIBC_NAMESPACE_DECL { +constinit ExitCallbackList at_quick_exit_callbacks; + LLVM_LIBC_FUNCTION(int, at_quick_exit, (__atexithandler_t callback)) { return add_atexit_unit( at_quick_exit_callbacks, diff --git a/libc/src/stdlib/atexit.cpp b/libc/src/stdlib/atexit.cpp index 6844fb7aacaf61..c8a15dd3cfef2d 100644 --- a/libc/src/stdlib/atexit.cpp +++ b/libc/src/stdlib/atexit.cpp @@ -14,6 +14,9 @@ namespace LIBC_NAMESPACE_DECL { +constinit ExitCallbackList atexit_callbacks; +Mutex handler_list_mtx(false, false, false, false); + extern "C" { int __cxa_atexit(AtExitCallback *callback, void *payload, void *) { diff --git a/libc/src/stdlib/exit_handler.cpp b/libc/src/stdlib/exit_handler.cpp deleted file mode 100644 index ed0751a4c889ef..00000000000000 --- a/libc/src/stdlib/exit_handler.cpp +++ /dev/null @@ -1,43 +0,0 @@ -//===--- Implementation of exit_handler------------------------------------===// -// -// 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/exit_handler.h" -#include "src/__support/CPP/mutex.h" // lock_guard -#include "src/__support/macros/config.h" - -namespace LIBC_NAMESPACE_DECL { - -constinit ExitCallbackList at_quick_exit_callbacks; -constinit ExitCallbackList atexit_callbacks; - -Mutex handler_list_mtx(false, false, false, false); - -void stdc_at_exit_func(void *payload) { - reinterpret_cast(payload)(); -} - -void call_exit_callbacks(ExitCallbackList &callbacks) { - handler_list_mtx.lock(); - while (!callbacks.empty()) { - AtExitUnit &unit = callbacks.back(); - callbacks.pop_back(); - handler_list_mtx.unlock(); - unit.callback(unit.payload); - handler_list_mtx.lock(); - } - ExitCallbackList::destroy(&callbacks); -} - -int add_atexit_unit(ExitCallbackList &callbacks, const AtExitUnit &unit) { - cpp::lock_guard lock(handler_list_mtx); - if (callbacks.push_back(unit)) - return 0; - return -1; -} - -} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/stdlib/exit_handler.h b/libc/src/stdlib/exit_handler.h index 41733b7a0e7e5f..9720c5473940ee 100644 --- a/libc/src/stdlib/exit_handler.h +++ b/libc/src/stdlib/exit_handler.h @@ -38,16 +38,32 @@ using ExitCallbackList = ReverseOrderBlockStore; using ExitCallbackList = FixedVector; #endif -extern ExitCallbackList atexit_callbacks; -extern ExitCallbackList at_quick_exit_callbacks; - +// This is handled by the 'atexit' implementation and shared by 'at_quick_exit'. extern Mutex handler_list_mtx; -void stdc_at_exit_func(void *payload); +LIBC_INLINE void stdc_at_exit_func(void *payload) { + reinterpret_cast(payload)(); +} -void call_exit_callbacks(ExitCallbackList &callbacks); +LIBC_INLINE void call_exit_callbacks(ExitCallbackList &callbacks) { + handler_list_mtx.lock(); + while (!callbacks.empty()) { + AtExitUnit &unit = callbacks.back(); + callbacks.pop_back(); + handler_list_mtx.unlock(); + unit.callback(unit.payload); + handler_list_mtx.lock(); + } + ExitCallbackList::destroy(&callbacks); +} -int add_atexit_unit(ExitCallbackList &callbacks, const AtExitUnit &unit); +LIBC_INLINE int add_atexit_unit(ExitCallbackList &callbacks, + const AtExitUnit &unit) { + cpp::lock_guard lock(handler_list_mtx); + if (callbacks.push_back(unit)) + return 0; + return -1; +} } // namespace LIBC_NAMESPACE_DECL