[index] Allow TxIndex sync thread to be interrupted.

This commit is contained in:
Jim Posen 2017-12-08 10:52:42 -08:00
parent 94b4f8bbb9
commit 70d510d93c
4 changed files with 30 additions and 3 deletions

View File

@ -30,6 +30,12 @@ TxIndex::TxIndex(std::unique_ptr<TxIndexDB> db) :
m_db(std::move(db)), m_synced(false), m_best_block_index(nullptr) m_db(std::move(db)), m_synced(false), m_best_block_index(nullptr)
{} {}
TxIndex::~TxIndex()
{
Interrupt();
Stop();
}
bool TxIndex::Init() bool TxIndex::Init()
{ {
LOCK(cs_main); LOCK(cs_main);
@ -76,6 +82,11 @@ void TxIndex::ThreadSync()
int64_t last_log_time = 0; int64_t last_log_time = 0;
int64_t last_locator_write_time = 0; int64_t last_locator_write_time = 0;
while (true) { while (true) {
if (m_interrupt) {
WriteBestBlock(pindex);
return;
}
{ {
LOCK(cs_main); LOCK(cs_main);
const CBlockIndex* pindex_next = NextSyncBlock(pindex); const CBlockIndex* pindex_next = NextSyncBlock(pindex);
@ -222,6 +233,11 @@ bool TxIndex::FindTx(const uint256& txid, CDiskTxPos& pos) const
return m_db->ReadTxPos(txid, pos); return m_db->ReadTxPos(txid, pos);
} }
void TxIndex::Interrupt()
{
m_interrupt();
}
void TxIndex::Start() void TxIndex::Start()
{ {
// Need to register this ValidationInterface before running Init(), so that // Need to register this ValidationInterface before running Init(), so that

View File

@ -6,6 +6,7 @@
#define BITCOIN_INDEX_TXINDEX_H #define BITCOIN_INDEX_TXINDEX_H
#include <primitives/block.h> #include <primitives/block.h>
#include <threadinterrupt.h>
#include <txdb.h> #include <txdb.h>
#include <uint256.h> #include <uint256.h>
#include <validationinterface.h> #include <validationinterface.h>
@ -31,14 +32,16 @@ private:
std::atomic<const CBlockIndex*> m_best_block_index; std::atomic<const CBlockIndex*> m_best_block_index;
std::thread m_thread_sync; std::thread m_thread_sync;
CThreadInterrupt m_interrupt;
/// Initialize internal state from the database and block index. /// Initialize internal state from the database and block index.
bool Init(); bool Init();
/// Sync the tx index with the block index starting from the current best /// Sync the tx index with the block index starting from the current best
/// block. Intended to be run in its own thread, m_thread_sync. Once the /// block. Intended to be run in its own thread, m_thread_sync, and can be
/// txindex gets in sync, the m_synced flag is set and the BlockConnected /// interrupted with m_interrupt. Once the txindex gets in sync, the
/// ValidationInterface callback takes over and the sync thread exits. /// m_synced flag is set and the BlockConnected ValidationInterface callback
/// takes over and the sync thread exits.
void ThreadSync(); void ThreadSync();
/// Write update index entries for a newly connected block. /// Write update index entries for a newly connected block.
@ -57,9 +60,14 @@ public:
/// Constructs the TxIndex, which becomes available to be queried. /// Constructs the TxIndex, which becomes available to be queried.
explicit TxIndex(std::unique_ptr<TxIndexDB> db); explicit TxIndex(std::unique_ptr<TxIndexDB> db);
/// Destructor interrupts sync thread if running and blocks until it exits.
~TxIndex();
/// Look up the on-disk location of a transaction by hash. /// Look up the on-disk location of a transaction by hash.
bool FindTx(const uint256& txid, CDiskTxPos& pos) const; bool FindTx(const uint256& txid, CDiskTxPos& pos) const;
void Interrupt();
/// Start initializes the sync state and registers the instance as a /// Start initializes the sync state and registers the instance as a
/// ValidationInterface so that it stays in sync with blockchain updates. /// ValidationInterface so that it stays in sync with blockchain updates.
void Start(); void Start();

View File

@ -5,6 +5,8 @@
#include <threadinterrupt.h> #include <threadinterrupt.h>
CThreadInterrupt::CThreadInterrupt() : flag(false) {}
CThreadInterrupt::operator bool() const CThreadInterrupt::operator bool() const
{ {
return flag.load(std::memory_order_acquire); return flag.load(std::memory_order_acquire);

View File

@ -18,6 +18,7 @@
class CThreadInterrupt class CThreadInterrupt
{ {
public: public:
CThreadInterrupt();
explicit operator bool() const; explicit operator bool() const;
void operator()(); void operator()();
void reset(); void reset();