diff options
Diffstat (limited to 'src/scheduler.cpp')
| -rw-r--r-- | src/scheduler.cpp | 23 |
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) |