diff options
author | Geert Bosch <geert@mongodb.com> | 2015-04-27 18:02:49 -0400 |
---|---|---|
committer | Geert Bosch <geert@mongodb.com> | 2015-05-07 17:00:50 -0400 |
commit | 465ba933e8d6f5ad9173c4c806686b915bfffe1c (patch) | |
tree | 80874f0de721267d18a399144f4cef691dc2329e /src/mongo/db/concurrency/lock_manager_defs.h | |
parent | 97b5712600ada8439f024f6bf446172f0fc9a7aa (diff) | |
download | mongo-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.h | 45 |
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. |