From 20a5fb31ef77f9baedce4da5011d72fcfc749bd9 Mon Sep 17 00:00:00 2001 From: Igor Canadi Date: Thu, 16 Oct 2014 13:06:13 -0700 Subject: [PATCH] Introduce onCollectionLock & onCollectionUnlock callbacks --- src/mongo/db/concurrency/d_concurrency.cpp | 14 +++++++++++++- src/mongo/db/concurrency/d_concurrency.h | 2 ++ src/mongo/db/storage/kv/kv_engine.h | 5 +++++ src/mongo/db/storage/kv/kv_storage_engine.cpp | 9 +++++++++ src/mongo/db/storage/kv/kv_storage_engine.h | 4 ++++ src/mongo/db/storage/rocks/SConscript | 1 + src/mongo/db/storage/rocks/rocks_engine.cpp | 16 ++++++++++++++++ src/mongo/db/storage/rocks/rocks_engine.h | 5 +++++ src/mongo/db/storage/storage_engine.h | 5 +++++ 9 files changed, 60 insertions(+), 1 deletion(-) diff --git a/src/mongo/db/concurrency/d_concurrency.cpp b/src/mongo/db/concurrency/d_concurrency.cpp index 63e9b5f..32eb01f 100644 --- a/src/mongo/db/concurrency/d_concurrency.cpp +++ b/src/mongo/db/concurrency/d_concurrency.cpp @@ -251,7 +251,9 @@ namespace mongo { const StringData& ns, LockMode mode) : _id(RESOURCE_COLLECTION, ns), - _lockState(lockState) { + _lockState(lockState), + _ns(ns.toString()), + _mode(mode) { const bool isRead = (mode == MODE_S || mode == MODE_IS); dassert(!ns.empty()); dassert(nsIsFull(ns)); @@ -260,12 +262,22 @@ namespace mongo { isRead ? MODE_IS : MODE_IX)); if (supportsDocLocking()) { _lockState->lock(_id, mode); + StorageEngine* storageEngine = getGlobalEnvironment()->getGlobalStorageEngine(); + if (storageEngine) { + storageEngine->onCollectionLock(_lockState, _ns, _mode); + } } else if (enableCollectionLocking) { _lockState->lock(_id, isRead ? MODE_S : MODE_X); } } Lock::CollectionLock::~CollectionLock() { + if (supportsDocLocking()) { + StorageEngine* storageEngine = getGlobalEnvironment()->getGlobalStorageEngine(); + if (storageEngine) { + storageEngine->onCollectionUnlock(_lockState, _ns, _mode); + } + } if (supportsDocLocking() || enableCollectionLocking) { _lockState->unlock(_id); } diff --git a/src/mongo/db/concurrency/d_concurrency.h b/src/mongo/db/concurrency/d_concurrency.h index 82c41d5..ce00d56 100644 --- a/src/mongo/db/concurrency/d_concurrency.h +++ b/src/mongo/db/concurrency/d_concurrency.h @@ -206,6 +206,8 @@ namespace mongo { private: const ResourceId _id; Locker* _lockState; + std::string _ns; + LockMode _mode; }; /** diff --git a/src/mongo/db/storage/kv/kv_engine.h b/src/mongo/db/storage/kv/kv_engine.h index 77b85e7..ca49adb 100644 --- a/src/mongo/db/storage/kv/kv_engine.h +++ b/src/mongo/db/storage/kv/kv_engine.h @@ -33,6 +33,7 @@ #include "mongo/base/status.h" #include "mongo/base/string_data.h" #include "mongo/db/catalog/collection_options.h" +#include "mongo/db/concurrency/lock_mgr_defs.h" namespace mongo { @@ -41,6 +42,7 @@ namespace mongo { class RecordStore; class RecoveryUnit; class SortedDataInterface; + class Locker; class KVEngine { public: @@ -85,6 +87,9 @@ namespace mongo { virtual Status dropSortedDataInterface( OperationContext* opCtx, const StringData& ident ) = 0; + + virtual void onCollectionLock(Locker* lockState, const StringData& ns, LockMode mode) {} + virtual void onCollectionUnlock(Locker* lockState, const StringData& ns, LockMode mode) {} }; } diff --git a/src/mongo/db/storage/kv/kv_storage_engine.cpp b/src/mongo/db/storage/kv/kv_storage_engine.cpp index 67109da..5dc84ea 100644 --- a/src/mongo/db/storage/kv/kv_storage_engine.cpp +++ b/src/mongo/db/storage/kv/kv_storage_engine.cpp @@ -36,6 +36,7 @@ #include "mongo/db/storage/kv/kv_database_catalog_entry.h" #include "mongo/db/storage/kv/kv_engine.h" #include "mongo/util/log.h" +#include "mongo/db/concurrency/locker.h" namespace mongo { @@ -60,6 +61,14 @@ namespace mongo { _engine.reset( NULL ); } + void KVStorageEngine::onCollectionLock(Locker* lockState, const StringData& ns, LockMode mode) { + _engine->onCollectionLock(lockState, ns, mode); + } + void KVStorageEngine::onCollectionUnlock(Locker* lockState, const StringData& ns, + LockMode mode) { + _engine->onCollectionUnlock(lockState, ns, mode); + } + KVStorageEngine::~KVStorageEngine() { } diff --git a/src/mongo/db/storage/kv/kv_storage_engine.h b/src/mongo/db/storage/kv/kv_storage_engine.h index b1dba3a..e179836 100644 --- a/src/mongo/db/storage/kv/kv_storage_engine.h +++ b/src/mongo/db/storage/kv/kv_storage_engine.h @@ -45,6 +45,7 @@ namespace mongo { class KVCatalog; class KVEngine; class KVDatabaseCatalogEntry; + class Locker; class KVStorageEngine : public StorageEngine { public: @@ -78,6 +79,9 @@ namespace mongo { virtual void cleanShutdown(OperationContext* txn); + virtual void onCollectionLock(Locker* lockState, const StringData& ns, LockMode mode); + virtual void onCollectionUnlock(Locker* lockState, const StringData& ns, LockMode mode); + // ------ kv ------ KVEngine* getEngine() { return _engine.get(); } diff --git a/src/mongo/db/storage/rocks/SConscript b/src/mongo/db/storage/rocks/SConscript index e79adc4..e9a0bef 100644 --- a/src/mongo/db/storage/rocks/SConscript +++ b/src/mongo/db/storage/rocks/SConscript @@ -14,6 +14,7 @@ if has_option("rocksdb"): LIBDEPS= [ '$BUILD_DIR/mongo/bson', '$BUILD_DIR/mongo/db/catalog/collection_options', + '$BUILD_DIR/mongo/db/concurrency/lock_mgr', '$BUILD_DIR/mongo/db/index/index_descriptor', '$BUILD_DIR/mongo/db/storage/bson_collection_catalog_entry', '$BUILD_DIR/mongo/db/storage/index_entry_comparison', diff --git a/src/mongo/db/storage/rocks/rocks_engine.cpp b/src/mongo/db/storage/rocks/rocks_engine.cpp index 6c9742b..b4d3d0f 100644 --- a/src/mongo/db/storage/rocks/rocks_engine.cpp +++ b/src/mongo/db/storage/rocks/rocks_engine.cpp @@ -44,6 +44,8 @@ #include #include "mongo/db/catalog/collection_options.h" +#include "mongo/db/concurrency/locker.h" +#include "mongo/db/concurrency/lock_mgr_defs.h" #include "mongo/db/index/index_descriptor.h" #include "mongo/db/operation_context.h" #include "mongo/db/storage/rocks/rocks_record_store.h" @@ -190,6 +192,20 @@ namespace mongo { return _dropColumnFamily(ident); } + void RocksEngine::onCollectionLock(Locker* lockState, const StringData& ns, LockMode mode) { + if (mode == MODE_IX) { + ResourceId rid(RESOURCE_DOCUMENT, ns); + lockState->lock(rid, MODE_X); + } + } + + void RocksEngine::onCollectionUnlock(Locker* lockState, const StringData& ns, LockMode mode) { + if (mode == MODE_IX) { + ResourceId rid(RESOURCE_DOCUMENT, ns); + lockState->unlock(rid); + } + } + // non public api rocksdb::ReadOptions RocksEngine::readOptionsWithSnapshot( OperationContext* opCtx ) { diff --git a/src/mongo/db/storage/rocks/rocks_engine.h b/src/mongo/db/storage/rocks/rocks_engine.h index e184f25..0dea537 100644 --- a/src/mongo/db/storage/rocks/rocks_engine.h +++ b/src/mongo/db/storage/rocks/rocks_engine.h @@ -92,6 +92,11 @@ namespace mongo { virtual Status dropSortedDataInterface(OperationContext* opCtx, const StringData& ident) override; + virtual void onCollectionLock(Locker* lockState, const StringData& ns, + LockMode mode) override; + virtual void onCollectionUnlock(Locker* lockState, const StringData& ns, + LockMode mode) override; + // rocks specific api rocksdb::DB* getDB() { return _db.get(); } diff --git a/src/mongo/db/storage/storage_engine.h b/src/mongo/db/storage/storage_engine.h index 04d896f..4871338 100644 --- a/src/mongo/db/storage/storage_engine.h +++ b/src/mongo/db/storage/storage_engine.h @@ -34,12 +34,14 @@ #include #include "mongo/base/status.h" +#include "mongo/db/concurrency/lock_mgr_defs.h" namespace mongo { class DatabaseCatalogEntry; class OperationContext; class RecoveryUnit; + class Locker; struct StorageGlobalParams; /** @@ -136,6 +138,9 @@ namespace mongo { */ virtual void cleanShutdown(OperationContext* txn) {} + virtual void onCollectionLock(Locker* lockState, const StringData& ns, LockMode mode) {} + virtual void onCollectionUnlock(Locker* lockerState, const StringData& ns, LockMode mode) {} + protected: /** * The destructor will never be called. See cleanShutdown instead. -- 1.8.1