diff options
author | Ian Moffett <ian@osmora.org> | 2024-03-07 17:28:00 -0500 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2024-03-07 17:28:32 -0500 |
commit | bd5969fc876a10b18613302db7087ef3c40f18e1 (patch) | |
tree | 7c2b8619afe902abf99570df2873fbdf40a4d1a1 /lib/mlibc/options/lsb/generic/dso_exit.cpp | |
parent | a95b38b1b92b172e6cc4e8e56a88a30cc65907b0 (diff) |
lib: Add mlibc
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'lib/mlibc/options/lsb/generic/dso_exit.cpp')
-rw-r--r-- | lib/mlibc/options/lsb/generic/dso_exit.cpp | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/lib/mlibc/options/lsb/generic/dso_exit.cpp b/lib/mlibc/options/lsb/generic/dso_exit.cpp new file mode 100644 index 0000000..b8b239d --- /dev/null +++ b/lib/mlibc/options/lsb/generic/dso_exit.cpp @@ -0,0 +1,42 @@ + +// for memcpy() +#include <string.h> + +#include <bits/ensure.h> +#include <mlibc/allocator.hpp> + +#include <frg/eternal.hpp> +#include <frg/vector.hpp> + +struct ExitHandler { + void (*function)(void *); + void *argument; + void *dsoHandle; +}; + +using ExitQueue = frg::vector<ExitHandler, MemoryAllocator>; + +ExitQueue &getExitQueue() { + // use frg::eternal to prevent the compiler from scheduling the destructor + // by generating a call to __cxa_atexit(). + static frg::eternal<ExitQueue> singleton(getAllocator()); + return singleton.get(); +} + +extern "C" int __cxa_atexit(void (*function)(void *), void *argument, void *handle) { + ExitHandler handler; + handler.function = function; + handler.argument = argument; + handler.dsoHandle = handle; + getExitQueue().push(handler); + return 0; +} + +void __mlibc_do_finalize() { + ExitQueue &eq = getExitQueue(); + for(size_t i = eq.size(); i > 0; i--) { + auto handler = &eq[i - 1]; + handler->function(handler->argument); + } +} + |