Merge pull request #2977

c70e8daa threadpool: fix deadlock in recursive waiter usage (moneromooo-monero)
This commit is contained in:
Riccardo Spagni 2018-01-02 00:31:56 +02:00
commit aa4195e199
No known key found for this signature in database
GPG Key ID: 55432DF31CCD4FCD

View File

@ -34,6 +34,8 @@
#include "cryptonote_config.h" #include "cryptonote_config.h"
#include "common/util.h" #include "common/util.h"
static __thread int depth = 0;
namespace tools namespace tools
{ {
threadpool::threadpool() : running(true), active(0) { threadpool::threadpool() : running(true), active(0) {
@ -60,11 +62,13 @@ threadpool::~threadpool() {
void threadpool::submit(waiter *obj, std::function<void()> f) { void threadpool::submit(waiter *obj, std::function<void()> f) {
entry e = {obj, f}; entry e = {obj, f};
boost::unique_lock<boost::mutex> lock(mutex); boost::unique_lock<boost::mutex> lock(mutex);
if (active == max && !queue.empty()) { if ((active == max && !queue.empty()) || depth > 0) {
// if all available threads are already running // if all available threads are already running
// and there's work waiting, just run in current thread // and there's work waiting, just run in current thread
lock.unlock(); lock.unlock();
++depth;
f(); f();
--depth;
} else { } else {
if (obj) if (obj)
obj->inc(); obj->inc();
@ -106,7 +110,9 @@ void threadpool::run() {
e = queue.front(); e = queue.front();
queue.pop_front(); queue.pop_front();
lock.unlock(); lock.unlock();
++depth;
e.f(); e.f();
--depth;
if (e.wo) if (e.wo)
e.wo->dec(); e.wo->dec();