summaryrefslogtreecommitdiff
path: root/src/mongo/db/concurrency/lock_manager_defs.h
diff options
context:
space:
mode:
authorGeert Bosch <geert@mongodb.com>2015-04-27 18:02:49 -0400
committerGeert Bosch <geert@mongodb.com>2015-05-07 17:00:50 -0400
commit465ba933e8d6f5ad9173c4c806686b915bfffe1c (patch)
tree80874f0de721267d18a399144f4cef691dc2329e /src/mongo/db/concurrency/lock_manager_defs.h
parent97b5712600ada8439f024f6bf446172f0fc9a7aa (diff)
downloadmongo-465ba933e8d6f5ad9173c4c806686b915bfffe1c.tar.gz
SERVER-18190: Make ParallelBatchWriterMode use a LockManager managed lock
Diffstat (limited to 'src/mongo/db/concurrency/lock_manager_defs.h')
-rw-r--r--src/mongo/db/concurrency/lock_manager_defs.h45
1 files changed, 37 insertions, 8 deletions
diff --git a/src/mongo/db/concurrency/lock_manager_defs.h b/src/mongo/db/concurrency/lock_manager_defs.h
index 9c646fafd47..33cc0279ea9 100644
--- a/src/mongo/db/concurrency/lock_manager_defs.h
+++ b/src/mongo/db/concurrency/lock_manager_defs.h
@@ -136,16 +136,21 @@ namespace mongo {
/**
* Hierarchy of resource types. The lock manager knows nothing about this hierarchy, it is
- * purely logical. Resources of different types will never conflict with each other. While the
- * lock manager does not know or care about ordering, the general policy is that resources are
- * acquired in the order below. For example, one might first acquire a RESOURCE_GLOBAL and then
- * the desired RESOURCE_DATABASE, both using intent modes, and finally a RESOURCE_COLLECTION
- * in exclusive mode.
+ * purely logical. Resources of different types will never conflict with each other.
+ *
+ * While the lock manager does not know or care about ordering, the general policy is that
+ * resources are acquired in the order below. For example, one might first acquire a
+ * RESOURCE_GLOBAL and then the desired RESOURCE_DATABASE, both using intent modes, and
+ * finally a RESOURCE_COLLECTION in exclusive mode. When locking multiple resources of the
+ * same type, the canonical order is by resourceId order.
+ *
+ * It is OK to lock resources out of order, but it is the users responsibility to ensure
+ * ordering is consistent so deadlock cannot occur.
*/
enum ResourceType {
- // Special (singleton) resources
+ // Types used for special resources, use with a hash id from ResourceId::SingletonHashIds.
RESOURCE_INVALID = 0,
- RESOURCE_GLOBAL,
+ RESOURCE_GLOBAL, // Used for mode changes or global exclusive operations
RESOURCE_MMAPV1_FLUSH, // Necessary only for the MMAPv1 engine
// Generic resources
@@ -171,6 +176,17 @@ namespace mongo {
BOOST_STATIC_ASSERT(ResourceTypesCount <= (1 << resourceTypeBits));
public:
+ /**
+ * Assign hash ids for special resources to avoid accidental reuse of ids. For ids used
+ * with the same ResourceType, the order here must be the same as the locking order.
+ */
+ enum SingletonHashIds {
+ SINGLETON_INVALID = 0,
+ SINGLETON_PARALLEL_BATCH_WRITER_MODE,
+ SINGLETON_GLOBAL,
+ SINGLETON_MMAPV1_FLUSH
+ };
+
ResourceId() : _fullHash(0) { }
ResourceId(ResourceType type, StringData ns);
ResourceId(ResourceType type, const std::string& ns);
@@ -182,6 +198,11 @@ namespace mongo {
return _fullHash;
}
+ // This defines the canonical locking order, first by type and then hash id
+ bool operator<(const ResourceId& rhs) const {
+ return _fullHash < rhs._fullHash;
+ }
+
ResourceType getType() const {
return static_cast<ResourceType>(_fullHash >> (64 - resourceTypeBits));
}
@@ -193,7 +214,6 @@ namespace mongo {
std::string toString() const;
private:
-
/**
* The top 'resourceTypeBits' bits of '_fullHash' represent the resource type,
* while the remaining bits contain the bottom bits of the hashId. This avoids false
@@ -229,6 +249,15 @@ namespace mongo {
// are serialized (see SERVER-16092)
extern const ResourceId resourceIdAdminDB;
+ // Hardcoded resource id for ParallelBatchWriterMode. We use the same resource type
+ // as resourceIdGlobal. This will also ensure the waits are reported as global, which
+ // is appropriate. The lock will never be contended unless the parallel batch writers
+ // must stop all other accesses globally. This resource must be locked before all other
+ // resources (including resourceIdGlobal). Replication applier threads don't take this
+ // lock.
+ // TODO: Merge this with resourceIdGlobal
+ extern const ResourceId resourceIdParallelBatchWriterMode;
+
/**
* Interface on which granted lock requests will be notified. See the contract for the notify
* method for more information and also the LockManager::lock call.