Skip to content

Commit 64c525b

Browse files
TheBlueMattfurszy
authored andcommitted
Otherwise threads will try to continue modifying data structures while the dump process is being executed.
Flush CValidationInterface callbacks prior to destruction Note that the CScheduler thread cant be running at this point, it has already been stopped with the rest of the init threadgroup. Thus, just calling any remaining loose callbacks during Shutdown() is sane.
1 parent 8022463 commit 64c525b

File tree

6 files changed

+32
-0
lines changed

6 files changed

+32
-0
lines changed

src/init.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,19 @@ void PrepareShutdown()
265265
fFeeEstimatesInitialized = false;
266266
}
267267

268+
// FlushStateToDisk generates a SetBestChain callback, which we should avoid missing
269+
FlushStateToDisk();
270+
271+
// After there are no more peers/RPC left to give us new data which may generate
272+
// CValidationInterface callbacks, flush them...
273+
GetMainSignals().FlushBackgroundCallbacks();
274+
275+
// Any future callbacks will be dropped. This should absolutely be safe - if
276+
// missing a callback results in an unrecoverable situation, unclean shutdown
277+
// would too. The only reason to do the above flushes is to let the wallet catch
278+
// up with our current chain to avoid any strange pruning edge cases and make
279+
// next startup faster by avoiding rescan.
280+
268281
{
269282
LOCK(cs_main);
270283
if (pcoinsTip != NULL) {

src/scheduler.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,3 +171,12 @@ void SingleThreadedSchedulerClient::AddToProcessQueue(std::function<void (void)>
171171
}
172172
MaybeScheduleProcessQueue();
173173
}
174+
175+
void SingleThreadedSchedulerClient::EmptyQueue() {
176+
bool should_continue = true;
177+
while (should_continue) {
178+
ProcessQueue();
179+
LOCK(m_cs_callbacks_pending);
180+
should_continue = !m_callbacks_pending.empty();
181+
}
182+
}

src/scheduler.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ class SingleThreadedSchedulerClient {
102102
public:
103103
SingleThreadedSchedulerClient(CScheduler *pschedulerIn) : m_pscheduler(pschedulerIn) {}
104104
void AddToProcessQueue(std::function<void (void)> func);
105+
106+
// Processes all remaining queue members on the calling thread, blocking until queue is empty
107+
void EmptyQueue();
105108
};
106109

107110
#endif

src/test/test_pivx.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ TestingSetup::~TestingSetup()
8686
UnregisterNodeSignals(GetNodeSignals());
8787
threadGroup.interrupt_all();
8888
threadGroup.join_all();
89+
GetMainSignals().FlushBackgroundCallbacks();
8990
GetMainSignals().UnregisterBackgroundSignalScheduler();
9091
UnloadBlockIndex();
9192
delete pcoinsTip;

src/validationinterface.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ void CMainSignals::UnregisterBackgroundSignalScheduler() {
6666
m_internals.reset(nullptr);
6767
}
6868

69+
void CMainSignals::FlushBackgroundCallbacks() {
70+
m_internals->m_schedulerClient.EmptyQueue();
71+
}
72+
6973
CMainSignals& GetMainSignals()
7074
{
7175
return g_signals;

src/validationinterface.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ class CMainSignals {
6060
void RegisterBackgroundSignalScheduler(CScheduler& scheduler);
6161
/** Unregister a CScheduler to give callbacks which should run in the background - these callbacks will now be dropped! */
6262
void UnregisterBackgroundSignalScheduler();
63+
/** Call any remaining callbacks on the calling thread */
64+
void FlushBackgroundCallbacks();
6365

6466
void UpdatedBlockTip(const CBlockIndex *, const CBlockIndex *, bool fInitialDownload);
6567
void TransactionAddedToMempool(const CTransactionRef &ptxn);

0 commit comments

Comments
 (0)