aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Posen <jimpo@coinbase.com>2017-12-08 10:52:42 -0800
committerJim Posen <jimpo@coinbase.com>2018-04-25 11:25:09 -0700
commit70d510d93c08a168407f55c932ab09c644dea3b8 (patch)
treec20fd2b12e025dedc7e0447d077ac8ae753c1b18
parent94b4f8bbb9e7e37f3057b47bf13a74de12b8e0cc (diff)
downloadbitcoin-70d510d93c08a168407f55c932ab09c644dea3b8.tar.xz
[index] Allow TxIndex sync thread to be interrupted.
-rw-r--r--src/index/txindex.cpp16
-rw-r--r--src/index/txindex.h14
-rw-r--r--src/threadinterrupt.cpp2
-rw-r--r--src/threadinterrupt.h1
4 files changed, 30 insertions, 3 deletions
diff --git a/src/index/txindex.cpp b/src/index/txindex.cpp
index 56966021a9..82798fbcc1 100644
--- a/src/index/txindex.cpp
+++ b/src/index/txindex.cpp
@@ -30,6 +30,12 @@ TxIndex::TxIndex(std::unique_ptr<TxIndexDB> db) :
m_db(std::move(db)), m_synced(false), m_best_block_index(nullptr)
{}
+TxIndex::~TxIndex()
+{
+ Interrupt();
+ Stop();
+}
+
bool TxIndex::Init()
{
LOCK(cs_main);
@@ -76,6 +82,11 @@ void TxIndex::ThreadSync()
int64_t last_log_time = 0;
int64_t last_locator_write_time = 0;
while (true) {
+ if (m_interrupt) {
+ WriteBestBlock(pindex);
+ return;
+ }
+
{
LOCK(cs_main);
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);
}
+void TxIndex::Interrupt()
+{
+ m_interrupt();
+}
+
void TxIndex::Start()
{
// Need to register this ValidationInterface before running Init(), so that
diff --git a/src/index/txindex.h b/src/index/txindex.h
index 35d58d5b65..633aee46ce 100644
--- a/src/index/txindex.h
+++ b/src/index/txindex.h
@@ -6,6 +6,7 @@
#define BITCOIN_INDEX_TXINDEX_H
#include <primitives/block.h>
+#include <threadinterrupt.h>
#include <txdb.h>
#include <uint256.h>
#include <validationinterface.h>
@@ -31,14 +32,16 @@ private:
std::atomic<const CBlockIndex*> m_best_block_index;
std::thread m_thread_sync;
+ CThreadInterrupt m_interrupt;
/// Initialize internal state from the database and block index.
bool Init();
/// 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
- /// txindex gets in sync, the m_synced flag is set and the BlockConnected
- /// ValidationInterface callback takes over and the sync thread exits.
+ /// block. Intended to be run in its own thread, m_thread_sync, and can be
+ /// interrupted with m_interrupt. Once the txindex gets in sync, the
+ /// m_synced flag is set and the BlockConnected ValidationInterface callback
+ /// takes over and the sync thread exits.
void ThreadSync();
/// Write update index entries for a newly connected block.
@@ -57,9 +60,14 @@ public:
/// Constructs the TxIndex, which becomes available to be queried.
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.
bool FindTx(const uint256& txid, CDiskTxPos& pos) const;
+ void Interrupt();
+
/// Start initializes the sync state and registers the instance as a
/// ValidationInterface so that it stays in sync with blockchain updates.
void Start();
diff --git a/src/threadinterrupt.cpp b/src/threadinterrupt.cpp
index 5d932091cb..7da4e136ef 100644
--- a/src/threadinterrupt.cpp
+++ b/src/threadinterrupt.cpp
@@ -5,6 +5,8 @@
#include <threadinterrupt.h>
+CThreadInterrupt::CThreadInterrupt() : flag(false) {}
+
CThreadInterrupt::operator bool() const
{
return flag.load(std::memory_order_acquire);
diff --git a/src/threadinterrupt.h b/src/threadinterrupt.h
index 54e3102808..d373e3c371 100644
--- a/src/threadinterrupt.h
+++ b/src/threadinterrupt.h
@@ -18,6 +18,7 @@
class CThreadInterrupt
{
public:
+ CThreadInterrupt();
explicit operator bool() const;
void operator()();
void reset();