forked from lix-project/lix
ThreadPool: On exception, interrupt the other worker threads
This commit is contained in:
parent
6a888ec29a
commit
b7376edf06
|
@ -21,7 +21,7 @@ ThreadPool::~ThreadPool()
|
|||
std::vector<std::thread> workers;
|
||||
{
|
||||
auto state(state_.lock());
|
||||
state->quit = true;
|
||||
quit = true;
|
||||
std::swap(workers, state->workers);
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ ThreadPool::~ThreadPool()
|
|||
void ThreadPool::enqueue(const work_t & t)
|
||||
{
|
||||
auto state(state_.lock());
|
||||
if (state->quit)
|
||||
if (quit)
|
||||
throw ThreadPoolShutDown("cannot enqueue a work item while the thread pool is shutting down");
|
||||
state->left.push(t);
|
||||
if (state->left.size() > state->workers.size() && state->workers.size() < maxThreads)
|
||||
|
@ -63,6 +63,8 @@ void ThreadPool::process()
|
|||
|
||||
void ThreadPool::workerEntry()
|
||||
{
|
||||
interruptCheck = [&]() { return (bool) quit; };
|
||||
|
||||
bool didWork = false;
|
||||
std::exception_ptr exc;
|
||||
|
||||
|
@ -80,7 +82,7 @@ void ThreadPool::workerEntry()
|
|||
if (!state->exception) {
|
||||
state->exception = exc;
|
||||
// Tell the other workers to quit.
|
||||
state->quit = true;
|
||||
quit = true;
|
||||
work.notify_all();
|
||||
} else {
|
||||
/* Print the exception, since we can't
|
||||
|
@ -100,7 +102,7 @@ void ThreadPool::workerEntry()
|
|||
/* Wait until a work item is available or another thread
|
||||
had an exception or we're asked to quit. */
|
||||
while (true) {
|
||||
if (state->quit) {
|
||||
if (quit) {
|
||||
if (!state->active)
|
||||
done.notify_one();
|
||||
return;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <functional>
|
||||
#include <thread>
|
||||
#include <map>
|
||||
#include <atomic>
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
@ -47,9 +48,10 @@ private:
|
|||
size_t active = 0;
|
||||
std::exception_ptr exception;
|
||||
std::vector<std::thread> workers;
|
||||
bool quit = false;
|
||||
};
|
||||
|
||||
std::atomic_bool quit{false};
|
||||
|
||||
Sync<State> state_;
|
||||
|
||||
std::condition_variable work, done;
|
||||
|
|
|
@ -1002,6 +1002,7 @@ void closeOnExec(int fd)
|
|||
bool _isInterrupted = false;
|
||||
|
||||
static thread_local bool interruptThrown = false;
|
||||
thread_local std::function<bool()> interruptCheck;
|
||||
|
||||
void setInterruptThrown()
|
||||
{
|
||||
|
@ -1020,7 +1021,6 @@ void _interrupted()
|
|||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
|
@ -273,13 +273,16 @@ void closeOnExec(int fd);
|
|||
|
||||
extern bool _isInterrupted;
|
||||
|
||||
extern thread_local std::function<bool()> interruptCheck;
|
||||
|
||||
void setInterruptThrown();
|
||||
|
||||
void _interrupted();
|
||||
|
||||
void inline checkInterrupt()
|
||||
{
|
||||
if (_isInterrupted) _interrupted();
|
||||
if (_isInterrupted || (interruptCheck && interruptCheck()))
|
||||
_interrupted();
|
||||
}
|
||||
|
||||
MakeError(Interrupted, BaseError)
|
||||
|
|
Loading…
Reference in a new issue