mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-20 23:29:12 +01:00
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.
This commit is contained in:
@@ -139,3 +139,55 @@ size_t CScheduler::getQueueInfo(boost::chrono::system_clock::time_point &first,
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void SingleThreadedSchedulerClient::MaybeScheduleProcessQueue() {
|
||||
{
|
||||
LOCK(m_cs_callbacks_pending);
|
||||
// Try to avoid scheduling too many copies here, but if we
|
||||
// accidentally have two ProcessQueue's scheduled at once its
|
||||
// not a big deal.
|
||||
if (m_are_callbacks_running) return;
|
||||
if (m_callbacks_pending.empty()) return;
|
||||
}
|
||||
m_pscheduler->schedule(std::bind(&SingleThreadedSchedulerClient::ProcessQueue, this));
|
||||
}
|
||||
|
||||
void SingleThreadedSchedulerClient::ProcessQueue() {
|
||||
std::function<void (void)> callback;
|
||||
{
|
||||
LOCK(m_cs_callbacks_pending);
|
||||
if (m_are_callbacks_running) return;
|
||||
if (m_callbacks_pending.empty()) return;
|
||||
m_are_callbacks_running = true;
|
||||
|
||||
callback = std::move(m_callbacks_pending.front());
|
||||
m_callbacks_pending.pop_front();
|
||||
}
|
||||
|
||||
// RAII the setting of fCallbacksRunning and calling MaybeScheduleProcessQueue
|
||||
// to ensure both happen safely even if callback() throws.
|
||||
struct RAIICallbacksRunning {
|
||||
SingleThreadedSchedulerClient* instance;
|
||||
RAIICallbacksRunning(SingleThreadedSchedulerClient* _instance) : instance(_instance) {}
|
||||
~RAIICallbacksRunning() {
|
||||
{
|
||||
LOCK(instance->m_cs_callbacks_pending);
|
||||
instance->m_are_callbacks_running = false;
|
||||
}
|
||||
instance->MaybeScheduleProcessQueue();
|
||||
}
|
||||
} raiicallbacksrunning(this);
|
||||
|
||||
callback();
|
||||
}
|
||||
|
||||
void SingleThreadedSchedulerClient::AddToProcessQueue(std::function<void (void)> func) {
|
||||
assert(m_pscheduler);
|
||||
|
||||
{
|
||||
LOCK(m_cs_callbacks_pending);
|
||||
m_callbacks_pending.emplace_back(std::move(func));
|
||||
}
|
||||
MaybeScheduleProcessQueue();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user