mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-18 10:05:51 +00:00
Fix destructor race in Job
This commit is contained in:
@@ -180,7 +180,7 @@ private:
|
||||
//
|
||||
// Invariants:
|
||||
// <none>
|
||||
void finishJob (Job const& job);
|
||||
void finishJob (JobType type);
|
||||
|
||||
template <class Rep, class Period>
|
||||
void on_dequeue (JobType type,
|
||||
|
||||
@@ -80,6 +80,10 @@ void Job::doJob ()
|
||||
m_loadEvent->reName (mName);
|
||||
|
||||
mJob (*this);
|
||||
|
||||
// Destroy the lambda, otherwise we won't include
|
||||
// its duration in the time measurement
|
||||
mJob = std::function<void(Job&)>();
|
||||
}
|
||||
|
||||
void Job::rename (std::string const& newName)
|
||||
|
||||
@@ -407,14 +407,11 @@ JobQueue::getNextJob (Job& job)
|
||||
}
|
||||
|
||||
void
|
||||
JobQueue::finishJob (Job const& job)
|
||||
JobQueue::finishJob (JobType type)
|
||||
{
|
||||
JobType const type = job.getType ();
|
||||
assert(type != jtINVALID);
|
||||
|
||||
assert (m_jobSet.find (job) == m_jobSet.end ());
|
||||
assert (type != jtINVALID);
|
||||
|
||||
JobTypeData& data (getJobTypeData (type));
|
||||
JobTypeData& data = getJobTypeData (type);
|
||||
|
||||
// Queue a deferred task if possible
|
||||
if (data.deferred > 0)
|
||||
@@ -457,40 +454,49 @@ void JobQueue::on_execute (JobType type,
|
||||
void
|
||||
JobQueue::processTask ()
|
||||
{
|
||||
Job job;
|
||||
JobType type;
|
||||
|
||||
{
|
||||
std::lock_guard <std::mutex> lock (m_mutex);
|
||||
getNextJob (job);
|
||||
++m_processCount;
|
||||
}
|
||||
Job job;
|
||||
|
||||
JobTypeData& data (getJobTypeData (job.getType ()));
|
||||
{
|
||||
std::lock_guard <std::mutex> lock (m_mutex);
|
||||
getNextJob (job);
|
||||
++m_processCount;
|
||||
}
|
||||
|
||||
// Skip the job if we are stopping and the
|
||||
// skipOnStop flag is set for the job type
|
||||
//
|
||||
if (!isStopping() || !data.info.skip ())
|
||||
{
|
||||
beast::Thread::setCurrentThreadName (data.name ());
|
||||
JLOG(m_journal.trace) << "Doing " << data.name () << " job";
|
||||
JobTypeData& data (getJobTypeData (job.getType ()));
|
||||
|
||||
Job::clock_type::time_point const start_time (
|
||||
Job::clock_type::now());
|
||||
// Skip the job if we are stopping and the
|
||||
// skipOnStop flag is set for the job type
|
||||
//
|
||||
if (!isStopping() || !data.info.skip ())
|
||||
{
|
||||
beast::Thread::setCurrentThreadName (data.name ());
|
||||
JLOG(m_journal.trace) << "Doing " << data.name () << " job";
|
||||
|
||||
on_dequeue (job.getType (), start_time - job.queue_time ());
|
||||
job.doJob ();
|
||||
on_execute (job.getType (), Job::clock_type::now() - start_time);
|
||||
}
|
||||
else
|
||||
{
|
||||
JLOG(m_journal.trace) << "Skipping processTask ('" << data.name () << "')";
|
||||
Job::clock_type::time_point const start_time (
|
||||
Job::clock_type::now());
|
||||
|
||||
on_dequeue (job.getType (), start_time - job.queue_time ());
|
||||
job.doJob ();
|
||||
on_execute (job.getType (), Job::clock_type::now() - start_time);
|
||||
}
|
||||
else
|
||||
{
|
||||
JLOG(m_journal.trace) << "Skipping processTask ('" << data.name () << "')";
|
||||
}
|
||||
|
||||
type = job.getType();
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard <std::mutex> lock (m_mutex);
|
||||
finishJob (job);
|
||||
finishJob (type);
|
||||
--m_processCount;
|
||||
// Job should be destroyed before calling checkStopped
|
||||
// otherwise destructors with side effects can access
|
||||
// parent objects that are already destroyed.
|
||||
checkStopped (lock);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user