diff --git a/src/Makefile.am b/src/Makefile.am index 89b90e6dff..3428d4613d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -138,6 +138,7 @@ BITCOIN_CORE_H = \ support/lockedpool.h \ sync.h \ threadsafety.h \ + threadinterrupt.h \ timedata.h \ torcontrol.h \ txdb.h \ @@ -327,6 +328,7 @@ libbitcoin_util_a_SOURCES = \ rpc/protocol.cpp \ support/cleanse.cpp \ sync.cpp \ + threadinterrupt.cpp \ util.cpp \ utilmoneystr.cpp \ utilstrencodings.cpp \ diff --git a/src/threadinterrupt.cpp b/src/threadinterrupt.cpp new file mode 100644 index 0000000000..9d691079ed --- /dev/null +++ b/src/threadinterrupt.cpp @@ -0,0 +1,41 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-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 "threadinterrupt.h" + +CThreadInterrupt::operator bool() const +{ + return flag.load(std::memory_order_acquire); +} + +void CThreadInterrupt::reset() +{ + flag.store(false, std::memory_order_release); +} + +void CThreadInterrupt::operator()() +{ + { + std::unique_lock lock(mut); + flag.store(true, std::memory_order_release); + } + cond.notify_all(); +} + +bool CThreadInterrupt::sleep_for(std::chrono::milliseconds rel_time) +{ + std::unique_lock lock(mut); + return !cond.wait_for(lock, rel_time, [this]() { return flag.load(std::memory_order_acquire); }); +} + +bool CThreadInterrupt::sleep_for(std::chrono::seconds rel_time) +{ + return sleep_for(std::chrono::duration_cast(rel_time)); +} + +bool CThreadInterrupt::sleep_for(std::chrono::minutes rel_time) +{ + return sleep_for(std::chrono::duration_cast(rel_time)); +} diff --git a/src/threadinterrupt.h b/src/threadinterrupt.h new file mode 100644 index 0000000000..54e3102808 --- /dev/null +++ b/src/threadinterrupt.h @@ -0,0 +1,34 @@ +// Copyright (c) 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. + +#ifndef BITCOIN_THREADINTERRUPT_H +#define BITCOIN_THREADINTERRUPT_H + +#include +#include +#include +#include + +/* + A helper class for interruptible sleeps. Calling operator() will interrupt + any current sleep, and after that point operator bool() will return true + until reset. +*/ +class CThreadInterrupt +{ +public: + explicit operator bool() const; + void operator()(); + void reset(); + bool sleep_for(std::chrono::milliseconds rel_time); + bool sleep_for(std::chrono::seconds rel_time); + bool sleep_for(std::chrono::minutes rel_time); + +private: + std::condition_variable cond; + std::mutex mut; + std::atomic flag; +}; + +#endif //BITCOIN_THREADINTERRUPT_H