aboutsummaryrefslogtreecommitdiff
path: root/src/validationinterface.cpp
diff options
context:
space:
mode:
authorMatt Corallo <git@bluematt.me>2017-04-10 14:55:49 -0400
committerMatt Corallo <git@bluematt.me>2017-07-07 11:33:18 -0400
commit08096bbbc6d6fef86943ca8ce5e6de18744d58ea (patch)
treeb1199ad23ceb259db07d8f3fb3b6dbe4c996fefa /src/validationinterface.cpp
parent2fbf2dbe151e135586cc1bb05b891f2c8ab6c817 (diff)
Support more than one CScheduler thread for serial clients
This will be used by CValidationInterface soon. This requires a bit of work as we need to ensure that most of our callbacks happen in-order (to avoid synchronization issues in wallet) - we keep our own internal queue and push things onto it, scheduling a queue-draining function immediately upon new callbacks.
Diffstat (limited to 'src/validationinterface.cpp')
-rw-r--r--src/validationinterface.cpp22
1 files changed, 14 insertions, 8 deletions
diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp
index a17a08eee2..8edc7c398d 100644
--- a/src/validationinterface.cpp
+++ b/src/validationinterface.cpp
@@ -6,6 +6,11 @@
#include "validationinterface.h"
#include "init.h"
#include "scheduler.h"
+#include "sync.h"
+#include "util.h"
+
+#include <list>
+#include <atomic>
#include <boost/signals2/signal.hpp>
@@ -20,22 +25,23 @@ struct MainSignalsInstance {
boost::signals2::signal<void (const CBlock&, const CValidationState&)> BlockChecked;
boost::signals2::signal<void (const CBlockIndex *, const std::shared_ptr<const CBlock>&)> NewPoWValidBlock;
- CScheduler *m_scheduler = NULL;
+ // We are not allowed to assume the scheduler only runs in one thread,
+ // but must ensure all callbacks happen in-order, so we end up creating
+ // our own queue here :(
+ SingleThreadedSchedulerClient m_schedulerClient;
+
+ MainSignalsInstance(CScheduler *pscheduler) : m_schedulerClient(pscheduler) {}
};
static CMainSignals g_signals;
-CMainSignals::CMainSignals() {
- m_internals.reset(new MainSignalsInstance());
-}
-
void CMainSignals::RegisterBackgroundSignalScheduler(CScheduler& scheduler) {
- assert(!m_internals->m_scheduler);
- m_internals->m_scheduler = &scheduler;
+ assert(!m_internals);
+ m_internals.reset(new MainSignalsInstance(&scheduler));
}
void CMainSignals::UnregisterBackgroundSignalScheduler() {
- m_internals->m_scheduler = NULL;
+ m_internals.reset(nullptr);
}
CMainSignals& GetMainSignals()