diff options
author | Kaloian Manassiev <kaloian.manassiev@mongodb.com> | 2014-09-26 14:02:49 -0400 |
---|---|---|
committer | Kaloian Manassiev <kaloian.manassiev@mongodb.com> | 2014-10-06 17:30:12 -0400 |
commit | 101e026f45dea5e9e68520238495c89a476e6172 (patch) | |
tree | bbdd3710ffc5721527ad9f5682ef0dbb4876dfee /src/mongo/db/client.h | |
parent | 10c86dc6cad9853514148e0ab59894a0d29353b9 (diff) | |
download | mongo-101e026f45dea5e9e68520238495c89a476e6172.tar.gz |
SERVER-14668/SERVER-15294 Collection-level locking for all read paths
Diffstat (limited to 'src/mongo/db/client.h')
-rw-r--r-- | src/mongo/db/client.h | 83 |
1 files changed, 63 insertions, 20 deletions
diff --git a/src/mongo/db/client.h b/src/mongo/db/client.h index ef78f899154..a3eb0cee79e 100644 --- a/src/mongo/db/client.h +++ b/src/mongo/db/client.h @@ -39,6 +39,7 @@ #include "mongo/db/client_basic.h" #include "mongo/db/concurrency/d_concurrency.h" #include "mongo/db/lasterror.h" +#include "mongo/db/namespace_string.h" #include "mongo/db/operation_context.h" #include "mongo/util/concurrency/threadlocal.h" #include "mongo/util/paths.h" @@ -50,6 +51,7 @@ namespace mongo { class Database; class CurOp; class Client; + class Collection; class AbstractMessagingPort; @@ -128,22 +130,6 @@ namespace mongo { public: - class Context; - - /** "read lock, and set my context, all in one operation" - * This handles (if not recursively locked) opening an unopened database. - */ - class ReadContext : boost::noncopyable { - public: - ReadContext(OperationContext* txn, - const std::string& ns, - bool doVersion = true); - Context& ctx() { return *_c.get(); } - private: - scoped_ptr<Lock::DBRead> _lk; - scoped_ptr<Context> _c; - }; - /* Set database we want to use, then, restores when we finish (are out of scope) Note this is also helpful if an exception happens as the state if fixed up. */ @@ -159,9 +145,6 @@ namespace mongo { */ Context(OperationContext* txn, const std::string& ns, Database * db); - // used by ReadContext - Context(OperationContext* txn, const std::string& ns, Database *db, bool doVersion); - ~Context(); Client* getClient() const { return _client; } Database* db() const { return _db; } @@ -194,6 +177,7 @@ namespace mongo { Timer _timer; }; // class Client::Context + class WriteContext : boost::noncopyable { public: WriteContext(OperationContext* opCtx, const std::string& ns, bool doVersion = true); @@ -209,10 +193,69 @@ namespace mongo { Context _c; }; - }; // class Client + /** + * RAII-style class, which acquires a lock on the specified database in the requested mode and + * obtains a reference to the database. Used as a shortcut for calls to dbHolder().get(). + * + * It is guaranteed that locks will be released when this object goes out of scope, therefore + * the database reference returned by this class should not be retained. + * + * TODO: This should be moved outside of client.h (maybe dbhelpers.h) + */ + class AutoGetDb { + MONGO_DISALLOW_COPYING(AutoGetDb); + public: + AutoGetDb(OperationContext* txn, const StringData& ns, newlm::LockMode mode); + + Database* getDb() const { + return _db; + } + + private: + const Lock::DBLock _dbLock; + Database* const _db; + }; + + /** + * RAII-style class, which would acquire the appropritate hierarchy of locks for obtaining + * a particular collection and would retrieve a reference to the collection. + * + * It is guaranteed that locks will be released when this object goes out of scope, therefore + * database and collection references returned by this class should not be retained. + * + * TODO: This should be moved outside of client.h (maybe dbhelpers.h) + */ + class AutoGetCollectionForRead { + MONGO_DISALLOW_COPYING(AutoGetCollectionForRead); + public: + AutoGetCollectionForRead(OperationContext* txn, const std::string& ns); + AutoGetCollectionForRead(OperationContext* txn, const NamespaceString& nss); + ~AutoGetCollectionForRead(); + + Database* getDb() const { + return _db; + } + + Collection* getCollection() const { + return _coll; + } + + private: + void _init(); + + const Timer _timer; + OperationContext* const _txn; + const NamespaceString _nss; + const Lock::DBLock _dbLock; + + Database* _db; + Collection* _coll; + }; + + /** get the Client object for this thread. */ inline Client& cc() { Client * c = currentClient.get(); |