summaryrefslogtreecommitdiff
path: root/src/mongo/platform
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/platform')
-rw-r--r--src/mongo/platform/condition_variable.cpp2
-rw-r--r--src/mongo/platform/condition_variable.h14
-rw-r--r--src/mongo/platform/condition_variable_test.cpp6
-rw-r--r--src/mongo/platform/mutex.cpp18
-rw-r--r--src/mongo/platform/mutex.h66
5 files changed, 73 insertions, 33 deletions
diff --git a/src/mongo/platform/condition_variable.cpp b/src/mongo/platform/condition_variable.cpp
index 19abb58b8f8..ef6e64aaff7 100644
--- a/src/mongo/platform/condition_variable.cpp
+++ b/src/mongo/platform/condition_variable.cpp
@@ -27,6 +27,8 @@
* it in the license file.
*/
+#include "mongo/platform/basic.h"
+
#include "mongo/platform/condition_variable.h"
namespace mongo {
diff --git a/src/mongo/platform/condition_variable.h b/src/mongo/platform/condition_variable.h
index 885e4b82ccd..beca4f4dda9 100644
--- a/src/mongo/platform/condition_variable.h
+++ b/src/mongo/platform/condition_variable.h
@@ -28,10 +28,12 @@
*/
#pragma once
-#include "mongo/platform/basic.h"
+
+#include <chrono>
#include "mongo/platform/mutex.h"
#include "mongo/stdx/condition_variable.h"
+#include "mongo/util/duration.h"
#include "mongo/util/scopeguard.h"
namespace mongo {
@@ -46,8 +48,6 @@ public:
};
class ConditionVariable {
- friend class ::mongo::Waitable;
-
public:
static constexpr Milliseconds kUnfulfilledConditionVariableTimeout = Milliseconds(100);
@@ -79,8 +79,10 @@ public:
protected:
template <typename Callback>
- void _runWithNotifyable(Notifyable& notifyable, Callback&& cb) noexcept {
- _condvar._runWithNotifyable(notifyable, cb);
+ friend void runWithNotifyable(ConditionVariable& cv,
+ Notifyable& notifyable,
+ Callback&& cb) noexcept {
+ runWithNotifyable(cv._condvar, notifyable, std::forward<Callback>(cb));
}
private:
@@ -105,7 +107,7 @@ private:
}
if (_conditionVariableActions) {
- if constexpr (std::is_same<decltype(lock), Mutex>::value) {
+ if constexpr (std::is_same<decltype(lock), mongo::Mutex>::value) {
_conditionVariableActions->onUnfulfilledConditionVariable(lock.getName());
} else {
_conditionVariableActions->onUnfulfilledConditionVariable("AnonymousLock");
diff --git a/src/mongo/platform/condition_variable_test.cpp b/src/mongo/platform/condition_variable_test.cpp
index 88e7a40c617..69631e233f2 100644
--- a/src/mongo/platform/condition_variable_test.cpp
+++ b/src/mongo/platform/condition_variable_test.cpp
@@ -39,11 +39,11 @@ namespace mongo {
TEST(ConditionVariable, BasicSingleThread) {
unittest::Barrier barrier(2U);
ConditionVariable cv;
- Mutex m;
+ stdx::mutex m; // NOLINT
bool done = false;
stdx::thread worker([&]() {
- stdx::unique_lock<Mutex> lk(m);
+ stdx::unique_lock<stdx::mutex> lk(m);
barrier.countDownAndWait();
ASSERT(!done);
cv.wait(lk, [&] { return done; });
@@ -52,7 +52,7 @@ TEST(ConditionVariable, BasicSingleThread) {
barrier.countDownAndWait();
{
- stdx::unique_lock<Mutex> lk(m);
+ stdx::unique_lock<stdx::mutex> lk(m);
done = true;
}
cv.notify_one();
diff --git a/src/mongo/platform/mutex.cpp b/src/mongo/platform/mutex.cpp
index 49ececfd25e..ba7230f8e94 100644
--- a/src/mongo/platform/mutex.cpp
+++ b/src/mongo/platform/mutex.cpp
@@ -31,23 +31,19 @@
namespace mongo {
-namespace {
-std::unique_ptr<LockActions> gLockActions;
-}
-
void Mutex::lock() {
- auto hasLock = _mutex.try_lock_for(kContendedLockTimeout.toSystemDuration());
+ auto hasLock = _mutex.try_lock();
if (hasLock) {
return;
}
- if (gLockActions) {
- gLockActions->onContendedLock(_name);
+ if (auto actions = LockActions::getState().actions.load()) {
+ actions->onContendedLock(_name);
}
_mutex.lock();
}
void Mutex::unlock() {
- if (gLockActions) {
- gLockActions->onUnlock(_name);
+ if (auto actions = LockActions::getState().actions.load()) {
+ actions->onUnlock(_name);
}
_mutex.unlock();
}
@@ -55,8 +51,8 @@ bool Mutex::try_lock() {
return _mutex.try_lock();
}
-void Mutex::setLockActions(std::unique_ptr<LockActions> actions) {
- gLockActions = std::move(actions);
+void Mutex::LockActions::add(LockActions* actions) {
+ getState().actions.store(actions);
}
} // namespace mongo
diff --git a/src/mongo/platform/mutex.h b/src/mongo/platform/mutex.h
index ded61a90783..fe72b201d3a 100644
--- a/src/mongo/platform/mutex.h
+++ b/src/mongo/platform/mutex.h
@@ -33,40 +33,80 @@
#include "mongo/base/error_codes.h"
#include "mongo/base/string_data.h"
+#include "mongo/platform/atomic_word.h"
#include "mongo/stdx/mutex.h"
-#include "mongo/util/clock_source_mock.h"
+#include "mongo/util/duration.h"
namespace mongo {
-class LockActions {
+class Latch {
public:
- virtual ~LockActions() = default;
- virtual void onContendedLock(const StringData& name) = 0;
- virtual void onUnlock(const StringData& name) = 0;
+ virtual ~Latch() = default;
+
+ virtual void lock() = 0;
+ virtual void unlock() = 0;
+ virtual bool try_lock() = 0;
};
-class Mutex {
+class Mutex : public Latch {
public:
+ class LockActions;
static constexpr auto kAnonymousMutexStr = "AnonymousMutex"_sd;
- static constexpr Milliseconds kContendedLockTimeout = Milliseconds(100);
Mutex() : Mutex(kAnonymousMutexStr) {}
// Note that StringData is a view type, thus the underlying string for _name must outlive any
// given Mutex
explicit Mutex(const StringData& name) : _name(name) {}
- void lock();
- void unlock();
- bool try_lock();
+ void lock() override;
+ void unlock() override;
+ bool try_lock() override;
const StringData& getName() const {
return _name;
}
- static void setLockActions(std::unique_ptr<LockActions> actions);
-
private:
const StringData _name;
- stdx::timed_mutex _mutex;
+ stdx::mutex _mutex; // NOLINT
+};
+
+/**
+ * A set of actions to happen upon notable events on a Lockable-conceptualized type
+ */
+class Mutex::LockActions {
+ friend class Mutex;
+
+public:
+ virtual ~LockActions() = default;
+ /**
+ * Action to do when a lock cannot be immediately acquired
+ */
+ virtual void onContendedLock(const StringData& name) = 0;
+
+ /**
+ * Action to do when a lock is unlocked
+ */
+ virtual void onUnlock(const StringData& name) = 0;
+
+ /**
+ * This function adds a LockActions subclass to the triggers for certain actions.
+ *
+ * Note that currently there is only one LockActions in use at a time. As part of SERVER-42895,
+ * this will change so that there is a list of LockActions maintained.
+ *
+ * LockActions can only be added and not removed. If you wish to deactivate a LockActions
+ * subclass, please provide the switch on that subclass to noop its functions.
+ */
+ static void add(LockActions* actions);
+
+private:
+ static auto& getState() {
+ struct State {
+ AtomicWord<LockActions*> actions{nullptr};
+ };
+ static State state;
+ return state;
+ }
};
} // namespace mongo