diff options
author | Ali Mohammad Pur <ali.mpfard@gmail.com> | 2022-02-24 04:22:54 +0330 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-03-08 22:29:53 +0100 |
commit | 5d51e26caff61516d6fcf612c2e9ba72a82b699f (patch) | |
tree | 526f9a80c6ffde886180f420f073a340396ac3c4 | |
parent | 31a2ac94c75a32877a2f63ba8c30e6a43116fd73 (diff) | |
download | serenity-5d51e26caff61516d6fcf612c2e9ba72a82b699f.zip |
LibPthread: Partially implement pthread_cleanup_(push pop)
These are also supposed to run on cancellation, but we don't support
cancellation.
-rw-r--r-- | Userland/Libraries/LibPthread/pthread.cpp | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/Userland/Libraries/LibPthread/pthread.cpp b/Userland/Libraries/LibPthread/pthread.cpp index 38997a8139..e440fc1d7d 100644 --- a/Userland/Libraries/LibPthread/pthread.cpp +++ b/Userland/Libraries/LibPthread/pthread.cpp @@ -9,6 +9,7 @@ #include <AK/Debug.h> #include <AK/Format.h> #include <AK/StdLibExtras.h> +#include <AK/Vector.h> #include <Kernel/API/Syscall.h> #include <LibSystem/syscall.h> #include <bits/pthread_integration.h> @@ -37,6 +38,12 @@ static constexpr size_t highest_reasonable_stack_size = 8 * MiB; // That's the d __thread void* s_stack_location; __thread size_t s_stack_size; +struct CleanupHandler { + void (*function)(void*) { nullptr }; + void* argument { nullptr }; +}; +thread_local Vector<CleanupHandler> s_cleanup_handlers {}; + #define __RETURN_PTHREAD_ERROR(rc) \ return ((rc) < 0 ? -(rc) : 0) @@ -139,19 +146,23 @@ int pthread_create(pthread_t* thread, pthread_attr_t* attributes, void* (*start_ // https://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_exit.html void pthread_exit(void* value_ptr) { + while (!s_cleanup_handlers.is_empty()) + pthread_cleanup_pop(1); exit_thread(value_ptr, s_stack_location, s_stack_size); } // https://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_cleanup_push.html -void pthread_cleanup_push([[maybe_unused]] void (*routine)(void*), [[maybe_unused]] void* arg) +void pthread_cleanup_push(void (*routine)(void*), void* arg) { - TODO(); + s_cleanup_handlers.empend(routine, arg); } // https://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_cleanup_pop.html -void pthread_cleanup_pop([[maybe_unused]] int execute) +void pthread_cleanup_pop(int execute) { - TODO(); + auto entry = s_cleanup_handlers.take_last(); + if (execute != 0) + entry.function(entry.argument); } // https://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_join.html |