net: add CThreadInterrupt and InterruptibleSleep

This commit is contained in:
Cory Fields 2016-12-27 17:12:15 -05:00
parent 7325b15566
commit 799df9115f
3 changed files with 77 additions and 0 deletions

View file

@ -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 \

41
src/threadinterrupt.cpp Normal file
View file

@ -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<std::mutex> lock(mut);
flag.store(true, std::memory_order_release);
}
cond.notify_all();
}
bool CThreadInterrupt::sleep_for(std::chrono::milliseconds rel_time)
{
std::unique_lock<std::mutex> 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<std::chrono::milliseconds>(rel_time));
}
bool CThreadInterrupt::sleep_for(std::chrono::minutes rel_time)
{
return sleep_for(std::chrono::duration_cast<std::chrono::milliseconds>(rel_time));
}

34
src/threadinterrupt.h Normal file
View file

@ -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 <atomic>
#include <chrono>
#include <condition_variable>
#include <mutex>
/*
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<bool> flag;
};
#endif //BITCOIN_THREADINTERRUPT_H