summaryrefslogtreecommitdiff
path: root/src/mongo/db/concurrency/d_concurrency.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/concurrency/d_concurrency.h')
-rw-r--r--src/mongo/db/concurrency/d_concurrency.h123
1 files changed, 55 insertions, 68 deletions
diff --git a/src/mongo/db/concurrency/d_concurrency.h b/src/mongo/db/concurrency/d_concurrency.h
index ae8501303a7..b999c6103da 100644
--- a/src/mongo/db/concurrency/d_concurrency.h
+++ b/src/mongo/db/concurrency/d_concurrency.h
@@ -37,7 +37,6 @@
namespace mongo {
-class StringData;
class NamespaceStringOrUUID;
class Lock {
@@ -50,61 +49,60 @@ public:
* resources other than RESOURCE_GLOBAL, RESOURCE_DATABASE and RESOURCE_COLLECTION.
*/
class ResourceLock {
- ResourceLock(const ResourceLock&) = delete;
- ResourceLock& operator=(const ResourceLock&) = delete;
-
public:
- ResourceLock(Locker* locker, ResourceId rid, LockMode mode)
- : ResourceLock(nullptr, locker, rid, mode) {}
-
ResourceLock(OperationContext* opCtx,
- Locker* locker,
ResourceId rid,
LockMode mode,
Date_t deadline = Date_t::max())
- : _rid(rid), _locker(locker), _result(LOCK_INVALID) {
- lock(opCtx, mode, deadline);
+ : _opCtx(opCtx), _locker(_opCtx->lockState()), _rid(rid) {
+ _lock(mode, deadline);
+ }
+
+ // TODO (SERVER-69461): Do not any new usages of this constructor and get rid of it
+ ResourceLock(Locker* locker, ResourceId rid, LockMode mode)
+ : _opCtx(nullptr), _locker(locker), _rid(rid) {
+ _lock(mode);
}
ResourceLock(ResourceLock&& otherLock)
- : _rid(otherLock._rid), _locker(otherLock._locker), _result(otherLock._result) {
- // Mark as moved so the destructor doesn't invalidate the newly-
- // constructed lock.
+ : _opCtx(otherLock._opCtx),
+ _locker(otherLock._locker),
+ _rid(std::move(otherLock._rid)),
+ _result(otherLock._result) {
+ otherLock._opCtx = nullptr;
+ otherLock._locker = nullptr;
otherLock._result = LOCK_INVALID;
}
~ResourceLock() {
- if (isLocked()) {
- unlock();
- }
+ _unlock();
}
+ protected:
/**
* Acquires lock on this specified resource in the specified mode.
*
- * If 'opCtx' is provided, it will be used to interrupt a LOCK_WAITING state.
* If 'deadline' is provided, we will wait until 'deadline' for the lock to be granted.
* Otherwise, this parameter defaults to an infinite deadline.
*
* This function may throw an exception if it is interrupted.
*/
- void lock(OperationContext* opCtx, LockMode mode, Date_t deadline = Date_t::max());
-
- void unlock();
-
- bool isLocked() const {
+ void _lock(LockMode mode, Date_t deadline = Date_t::max());
+ void _unlock();
+ bool _isLocked() const {
return _result == LOCK_OK;
}
- private:
- const ResourceId _rid;
- Locker* const _locker;
+ OperationContext* _opCtx;
- LockResult _result;
- };
+ // TODO (SERVER-69461): Get rid of this field when the Locker-only constructor is removed.
+ Locker* _locker;
- class SharedLock;
- class ExclusiveLock;
+ ResourceId _rid;
+
+ private:
+ LockResult _result{LOCK_INVALID};
+ };
/**
* For use as general mutex or readers/writers lock, outside the general multi-granularity
@@ -118,7 +116,14 @@ public:
std::string getName() const {
return getName(_rid);
- };
+ }
+
+ /**
+ * Each instantiation of this class allocates a new ResourceId.
+ */
+ ResourceId getRid() const {
+ return _rid;
+ }
static std::string getName(ResourceId resourceId);
@@ -127,16 +132,6 @@ public:
bool isAtLeastReadLocked(Locker* locker);
private:
- friend class Lock::SharedLock;
- friend class Lock::ExclusiveLock;
-
- /**
- * Each instantiation of this class allocates a new ResourceId.
- */
- ResourceId rid() const {
- return _rid;
- }
-
const ResourceId _rid;
};
@@ -145,23 +140,25 @@ public:
*/
class ExclusiveLock : public ResourceLock {
public:
- ExclusiveLock(Locker* locker, ResourceMutex mutex)
- : ExclusiveLock(nullptr, locker, mutex) {}
+ ExclusiveLock(OperationContext* opCtx, ResourceMutex mutex)
+ : ResourceLock(opCtx, mutex.getRid(), MODE_X) {}
- /**
- * Interruptible lock acquisition.
- */
- ExclusiveLock(OperationContext* opCtx, Locker* locker, ResourceMutex mutex)
- : ResourceLock(opCtx, locker, mutex.rid(), MODE_X) {}
+ ExclusiveLock(Locker* locker, ResourceMutex mutex)
+ : ResourceLock(locker, mutex.getRid(), MODE_X) {}
- using ResourceLock::lock;
+ // Lock/unlock overloads to allow ExclusiveLock to be used with with stdx::unique_lock and
+ // stdx::condition_variable_any
- /**
- * Parameterless overload to allow ExclusiveLock to be used with stdx::unique_lock and
- * stdx::condition_variable_any
- */
void lock() {
- lock(nullptr, MODE_X);
+ _lock(MODE_X);
+ }
+
+ void unlock() {
+ _unlock();
+ }
+
+ bool isLocked() const {
+ return _isLocked();
}
};
@@ -172,13 +169,11 @@ public:
*/
class SharedLock : public ResourceLock {
public:
- SharedLock(Locker* locker, ResourceMutex mutex) : SharedLock(nullptr, locker, mutex) {}
+ SharedLock(OperationContext* opCtx, ResourceMutex mutex)
+ : ResourceLock(opCtx, mutex.getRid(), MODE_IS) {}
- /**
- * Interruptible lock acquisition.
- */
- SharedLock(OperationContext* opCtx, Locker* locker, ResourceMutex mutex)
- : ResourceLock(opCtx, locker, mutex.rid(), MODE_IS) {}
+ SharedLock(Locker* locker, ResourceMutex mutex)
+ : ResourceLock(locker, mutex.getRid(), MODE_IS) {}
};
/**
@@ -315,14 +310,6 @@ public:
DBLock(DBLock&&);
~DBLock();
- /**
- * Releases the DBLock and reacquires it with the new mode. The global intent
- * lock is retained (so the database can't disappear). Relocking from MODE_IS or
- * MODE_S to MODE_IX or MODE_X is not allowed to avoid violating the global intent.
- * Use relockWithMode() instead of upgrading to avoid deadlock.
- */
- void relockWithMode(LockMode newMode);
-
bool isLocked() const {
return _result == LOCK_OK;
}
@@ -386,7 +373,7 @@ public:
ParallelBatchWriterMode& operator=(const ParallelBatchWriterMode&) = delete;
public:
- explicit ParallelBatchWriterMode(Locker* lockState);
+ explicit ParallelBatchWriterMode(OperationContext* opCtx);
private:
ResourceLock _pbwm;