Fix deadlock in DatabaseOrdinary in case of exception while loading tables.

This commit is contained in:
Nikolai Kochetov 2018-12-05 15:50:23 +03:00
parent 715d120ed9
commit c6ad3a7189
2 changed files with 34 additions and 27 deletions

View File

@ -61,36 +61,12 @@ private:
class ExceptionHandler class ExceptionHandler
{ {
public: public:
void setException(std::exception_ptr && exception) void setException(std::exception_ptr && exception);
{ void throwIfException();
std::unique_lock<std::mutex> lock(mutex);
if (!first_exception)
first_exception = std::move(exception);
}
void throwIfException()
{
std::unique_lock<std::mutex> lock(mutex);
if (first_exception)
std::rethrow_exception(first_exception);
}
private: private:
std::exception_ptr first_exception; std::exception_ptr first_exception;
std::mutex mutex; std::mutex mutex;
}; };
ThreadPool::Job createExceptionHandledJob(ThreadPool::Job job, ExceptionHandler & handler) ThreadPool::Job createExceptionHandledJob(ThreadPool::Job job, ExceptionHandler & handler);
{
return [job{std::move(job)}, &handler] ()
{
try
{
job();
}
catch (...)
{
handler.setException(std::current_exception());
}
};
}

View File

@ -112,3 +112,34 @@ void ThreadPool::worker()
} }
} }
void ExceptionHandler::setException(std::exception_ptr && exception)
{
std::unique_lock<std::mutex> lock(mutex);
if (!first_exception)
first_exception = std::move(exception);
}
void ExceptionHandler::throwIfException()
{
std::unique_lock<std::mutex> lock(mutex);
if (first_exception)
std::rethrow_exception(first_exception);
}
ThreadPool::Job createExceptionHandledJob(ThreadPool::Job job, ExceptionHandler & handler)
{
return [job{std::move(job)}, &handler] ()
{
try
{
job();
}
catch (...)
{
handler.setException(std::current_exception());
}
};
}