diff options
author | Gregory Noma <gregory.noma@gmail.com> | 2023-03-01 15:49:37 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2023-03-01 18:01:23 +0000 |
commit | 06c0e32b550363f92f2fe7c5bb91f900a67c04b4 (patch) | |
tree | f7fc3754fd2afc204414f9c62be1696722d57f36 /src | |
parent | 83a485fb41041760670721b6327676551a4d59c4 (diff) | |
download | mongo-06c0e32b550363f92f2fe7c5bb91f900a67c04b4.tar.gz |
SERVER-74433 Stop jobs upon destruction of embedded periodic runner
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/embedded/periodic_runner_embedded.cpp | 24 | ||||
-rw-r--r-- | src/mongo/embedded/periodic_runner_embedded.h | 2 |
2 files changed, 25 insertions, 1 deletions
diff --git a/src/mongo/embedded/periodic_runner_embedded.cpp b/src/mongo/embedded/periodic_runner_embedded.cpp index 87adf0842ce..ac52b8535dc 100644 --- a/src/mongo/embedded/periodic_runner_embedded.cpp +++ b/src/mongo/embedded/periodic_runner_embedded.cpp @@ -49,6 +49,20 @@ struct PeriodicRunnerEmbedded::PeriodicJobSorter { PeriodicRunnerEmbedded::PeriodicRunnerEmbedded(ServiceContext* svc, ClockSource* clockSource) : _svc(svc), _clockSource(clockSource) {} +PeriodicRunnerEmbedded::~PeriodicRunnerEmbedded() { + stdx::lock_guard<Latch> lk{_mutex}; + + auto stopJob = [&lk](const std::shared_ptr<PeriodicJobImpl>& job) { + stdx::lock_guard<Latch> jobLk{job->_mutex}; + if (job->isAlive(jobLk)) { + job->_stopWithMasterAndJobLock(lk, jobLk); + } + }; + + std::for_each(_jobs.begin(), _jobs.end(), stopJob); + std::for_each(_Pausedjobs.begin(), _Pausedjobs.end(), stopJob); +} + auto PeriodicRunnerEmbedded::makeJob(PeriodicJob job) -> JobAnchor { auto impl = std::make_shared<PeriodicJobImpl>(std::move(job), this->_clockSource, this); @@ -161,10 +175,18 @@ void PeriodicRunnerEmbedded::PeriodicJobImpl::resume() { } void PeriodicRunnerEmbedded::PeriodicJobImpl::stop() { + // It's possible that the periodic runner has already been destructed, so first see if this job + // has already been stopped. If so, we can return early before accessing the periodic runner. + stdx::unique_lock<Latch> lk{_mutex}; + if (!isAlive(lk)) { + return; + } + lk.unlock(); + // Also take the master lock, the job lock is not held while executing the job and we must make // sure the user can invalidate it after this call. stdx::lock_guard<Latch> masterLock(_periodicRunner->_mutex); - stdx::lock_guard<Latch> lk(_mutex); + lk.lock(); if (isAlive(lk)) { _stopWithMasterAndJobLock(masterLock, lk); } diff --git a/src/mongo/embedded/periodic_runner_embedded.h b/src/mongo/embedded/periodic_runner_embedded.h index a8549fb0bba..caa5f46c26b 100644 --- a/src/mongo/embedded/periodic_runner_embedded.h +++ b/src/mongo/embedded/periodic_runner_embedded.h @@ -48,6 +48,8 @@ class PeriodicRunnerEmbedded : public PeriodicRunner { public: PeriodicRunnerEmbedded(ServiceContext* svc, ClockSource* clockSource); + ~PeriodicRunnerEmbedded(); + JobAnchor makeJob(PeriodicJob job) override; // Safe to call from multiple threads but will only execute on one thread at a time. |