aboutsummaryrefslogtreecommitdiff
path: root/src/scheduler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/scheduler.cpp')
-rw-r--r--src/scheduler.cpp23
1 files changed, 14 insertions, 9 deletions
diff --git a/src/scheduler.cpp b/src/scheduler.cpp
index d5bb588b7..b01170074 100644
--- a/src/scheduler.cpp
+++ b/src/scheduler.cpp
@@ -1,9 +1,11 @@
-// Copyright (c) 2015 The Bitcoin Core developers
+// Copyright (c) 2015-2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "scheduler.h"
+#include "reverselock.h"
+
#include <assert.h>
#include <boost/bind.hpp>
#include <utility>
@@ -52,9 +54,10 @@ void CScheduler::serviceQueue()
#else
// Some boost versions have a conflicting overload of wait_until that returns void.
// Explicitly use a template here to avoid hitting that overload.
- while (!shouldStop() && !taskQueue.empty() &&
- newTaskScheduled.wait_until<>(lock, taskQueue.begin()->first) != boost::cv_status::timeout) {
- // Keep waiting until timeout
+ while (!shouldStop() && !taskQueue.empty()) {
+ boost::chrono::system_clock::time_point timeToWaitFor = taskQueue.begin()->first;
+ if (newTaskScheduled.wait_until<>(lock, timeToWaitFor) == boost::cv_status::timeout)
+ break; // Exit loop after timeout, it means we reached the time of the event
}
#endif
// If there are multiple threads, the queue can empty while we're waiting (another
@@ -65,17 +68,19 @@ void CScheduler::serviceQueue()
Function f = taskQueue.begin()->second;
taskQueue.erase(taskQueue.begin());
- // Unlock before calling f, so it can reschedule itself or another task
- // without deadlocking:
- lock.unlock();
- f();
- lock.lock();
+ {
+ // Unlock before calling f, so it can reschedule itself or another task
+ // without deadlocking:
+ reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock);
+ f();
+ }
} catch (...) {
--nThreadsServicingQueue;
throw;
}
}
--nThreadsServicingQueue;
+ newTaskScheduled.notify_one();
}
void CScheduler::stop(bool drain)