summaryrefslogtreecommitdiff
path: root/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp
diff options
context:
space:
mode:
authorDianna Hohensee <dianna.hohensee@mongodb.com>2020-02-21 15:43:53 -0500
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-02-25 04:54:39 +0000
commit61ea39197455ca2e54135607e5625bb2c2796ec3 (patch)
tree3bd09fedce5fae037ac5f1d1b3473262de29a87a /src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp
parentf83f9dcc22156cdf3c3e16a040914806e2e17cf7 (diff)
downloadmongo-61ea39197455ca2e54135607e5625bb2c2796ec3.tar.gz
SERVER-46334 Eliminate the mutex held across JournalListener calls.
delete mode 100644 src/mongo/db/storage/journal_listener.cpp
Diffstat (limited to 'src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp')
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp45
1 files changed, 32 insertions, 13 deletions
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp
index 64ef2d146ed..b56f31fc455 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp
@@ -249,9 +249,15 @@ void WiredTigerSessionCache::waitUntilDurable(OperationContext* opCtx,
if (isEphemeral()) {
// Update the JournalListener before we return. As far as listeners are concerned, all
// writes are as 'durable' as they are ever going to get on an inMemory storage engine.
- stdx::unique_lock<Latch> lk(_journalListenerMutex, stdx::defer_lock);
- if (useListener == UseJournalListener::kUpdate) {
- auto token = _journalListener->getToken(opCtx, lk);
+ auto journalListener = [&]() -> JournalListener* {
+ // The JournalListener may not be set immediately, so we must check under a mutex so
+ // as not to access the variable while setting a JournalListener. A JournalListener
+ // is only allowed to be set once, so using the pointer outside of a mutex is safe.
+ stdx::unique_lock<Latch> lk(_journalListenerMutex);
+ return _journalListener;
+ }();
+ if (journalListener && useListener == UseJournalListener::kUpdate) {
+ auto token = _journalListener->getToken(opCtx);
_journalListener->onDurable(token);
}
return;
@@ -283,12 +289,16 @@ void WiredTigerSessionCache::waitUntilDurable(OperationContext* opCtx,
// Update a value that tracks the latest write that is safe across startup recovery (in
// the repl layer) and then report the time of that write as durable after we flush
// in-memory to disk.
- // Defer locking the mutex so that it can be locked after any collection locks that
- // may be acquired, which avoids deadlocks.
- stdx::unique_lock<Latch> lk(_journalListenerMutex, stdx::defer_lock);
+ auto journalListener = [&]() -> JournalListener* {
+ // The JournalListener may not be set immediately, so we must check under a mutex so
+ // as not to access the variable while setting a JournalListener. A JournalListener
+ // is only allowed to be set once, so using the pointer outside of a mutex is safe.
+ stdx::unique_lock<Latch> lk(_journalListenerMutex);
+ return _journalListener;
+ }();
boost::optional<JournalListener::Token> token;
- if (useListener == UseJournalListener::kUpdate) {
- token = _journalListener->getToken(opCtx, lk);
+ if (journalListener && useListener == UseJournalListener::kUpdate) {
+ token = _journalListener->getToken(opCtx);
}
auto config = syncType == Fsync::kCheckpointStableTimestamp ? "use_timestamp=true"
@@ -322,12 +332,16 @@ void WiredTigerSessionCache::waitUntilDurable(OperationContext* opCtx,
// Update a value that tracks the latest write that is safe across startup recovery (in the repl
// layer) and then report the time of that write as durable after we flush in-memory to disk.
- // Defer locking the mutex so that it can be locked after any collection locks that may be
- // acquired, which avoids deadlocks.
- stdx::unique_lock<Latch> jlk(_journalListenerMutex, stdx::defer_lock);
+ auto journalListener = [&]() -> JournalListener* {
+ // The JournalListener may not be set immediately, so we must check under a mutex so as not
+ // to access the variable while setting a JournalListener. A JournalListener is only allowed
+ // to be set once, so using the pointer outside of a mutex is safe.
+ stdx::unique_lock<Latch> lk(_journalListenerMutex);
+ return _journalListener;
+ }();
boost::optional<JournalListener::Token> token;
- if (useListener == UseJournalListener::kUpdate) {
- token = _journalListener->getToken(opCtx, jlk);
+ if (journalListener && useListener == UseJournalListener::kUpdate) {
+ token = _journalListener->getToken(opCtx);
}
// Initialize on first use.
@@ -525,6 +539,11 @@ void WiredTigerSessionCache::releaseSession(WiredTigerSession* session) {
void WiredTigerSessionCache::setJournalListener(JournalListener* jl) {
stdx::unique_lock<Latch> lk(_journalListenerMutex);
+
+ // A JournalListener can only be set once. Otherwise, accessing a copy of the _journalListener
+ // pointer without a mutex would be unsafe.
+ invariant(!_journalListener);
+
_journalListener = jl;
}