Skip to content

Commit 31cda26

Browse files
committed
Addendum to 1dc9368 ("Fix some threadpool flaws") to fix new crash
1 parent 8fc6d49 commit 31cda26

File tree

1 file changed

+18
-15
lines changed

1 file changed

+18
-15
lines changed

Shared/sdk/SharedUtil.ThreadPool.h

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -65,26 +65,29 @@ namespace SharedUtil
6565
#else
6666
using ReturnT = std::invoke_result_t<Func, Args...>;
6767
#endif
68-
auto ff = std::bind(std::forward<Func>(f), std::forward<Args>(args)...);
69-
auto task = std::make_shared<std::packaged_task<ReturnT()>>(ff);
70-
71-
// Package the task in a wrapper with a common void result
72-
// plus a skip flag for destruction without running the task
73-
std::packaged_task<void(bool)> resultTask([task](bool skip) {
74-
if (!skip)
75-
(*task)();
76-
// task automatically deleted when shared_ptr goes out of scope
77-
});
7868

79-
// Add task to queue and return future
69+
auto ff = std::bind(std::forward<Func>(f), std::forward<Args>(args)...);
70+
auto task = std::make_shared<std::packaged_task<ReturnT()>>(ff);
8071
std::future<ReturnT> res = task->get_future();
72+
8173
{
8274
std::unique_lock<std::mutex> lock(m_mutex);
8375
if (m_exit)
8476
{
85-
// Pool is shutting down - reject new tasks
86-
throw std::runtime_error("Cannot enqueue task: thread pool is shutting down");
77+
// Return failed future instead of throwing (avoids crash if caller ignores result)
78+
lock.unlock();
79+
std::promise<ReturnT> failedPromise;
80+
failedPromise.set_exception(std::make_exception_ptr(
81+
std::runtime_error("Cannot enqueue task: thread pool is shutting down")));
82+
return failedPromise.get_future();
8783
}
84+
85+
// Wrap task with skip flag for shutdown cleanup
86+
std::packaged_task<void(bool)> resultTask([task](bool skip) {
87+
if (!skip)
88+
(*task)();
89+
});
90+
8891
m_tasks.emplace(std::move(resultTask));
8992
}
9093
m_cv.notify_one();
@@ -95,11 +98,11 @@ namespace SharedUtil
9598
{
9699
{
97100
std::unique_lock<std::mutex> lock(m_mutex);
98-
101+
99102
// Already shutting down or shut down
100103
if (m_exit)
101104
return;
102-
105+
103106
m_exit = true;
104107

105108
// Clear all remaining tasks (they will be destroyed automatically)

0 commit comments

Comments
 (0)