summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGregory Noma <gregory.noma@gmail.com>2023-03-01 15:49:37 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2023-03-01 18:01:23 +0000
commit06c0e32b550363f92f2fe7c5bb91f900a67c04b4 (patch)
treef7fc3754fd2afc204414f9c62be1696722d57f36 /src
parent83a485fb41041760670721b6327676551a4d59c4 (diff)
downloadmongo-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.cpp24
-rw-r--r--src/mongo/embedded/periodic_runner_embedded.h2
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.