From e691cdad6471b820b5205f2368eaa9f577497c94 Mon Sep 17 00:00:00 2001 From: "Fiorentino, Stefano" Date: Fri, 7 Jul 2023 16:15:13 +0200 Subject: [PATCH] Proposal for fixing the issue #292 Signed-off-by: Fiorentino, Stefano --- src/uvw/thread.cpp | 8 ++++++-- src/uvw/thread.h | 1 + test/uvw/thread.cpp | 28 ++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/uvw/thread.cpp b/src/uvw/thread.cpp index c1cecf71..d5808d6a 100644 --- a/src/uvw/thread.cpp +++ b/src/uvw/thread.cpp @@ -9,7 +9,8 @@ namespace uvw { UVW_INLINE thread::thread(loop::token token, std::shared_ptr ref, task t, std::shared_ptr d) noexcept : uv_type{token, std::move(ref)}, data{std::move(d)}, - func{std::move(t)} {} + func{std::move(t)}, + joined{false} {} UVW_INLINE void thread::create_callback(void *arg) { thread &curr = *(static_cast(arg)); @@ -42,7 +43,10 @@ UVW_INLINE bool thread::run(create_flags opts, std::size_t stack) noexcept { } UVW_INLINE bool thread::join() noexcept { - return (0 == uv_thread_join(raw())); + if(!joined && 0 == uv_thread_join(raw())) { + joined = true; + } + return joined; } UVW_INLINE thread_local_storage::thread_local_storage(loop::token token, std::shared_ptr ref) noexcept diff --git a/src/uvw/thread.h b/src/uvw/thread.h index 6d65d7e1..7b45b686 100644 --- a/src/uvw/thread.h +++ b/src/uvw/thread.h @@ -106,6 +106,7 @@ class thread final: public uv_type { private: std::shared_ptr data; task func; + bool joined; }; /** diff --git a/test/uvw/thread.cpp b/test/uvw/thread.cpp index 6960bd88..4493ec7e 100644 --- a/test/uvw/thread.cpp +++ b/test/uvw/thread.cpp @@ -72,3 +72,31 @@ TEST(Mutex, RecursiveLockUnlock) { loop->run(); } + +TEST(Thread, joined) +{ + auto loop = uvw::loop::get_default(); + auto threadWorker = [](std::shared_ptr d) { + std::cout << "all done" << std::endl; + }; + + std::vector> threads; + for (int i = 0; i < 8; i++) + { + auto threadId = std::make_shared(i); + auto threadHandle = loop->resource(threadWorker, threadId); + threads.push_back(threadHandle); + } + + for (auto& threadHandle : threads) + { + threadHandle->run(); + } + + loop->run(); + + for (auto& threadHandle : threads) + { + threadHandle->join(); + } +}