summaryrefslogtreecommitdiff
path: root/src/mongo/db/client.h
diff options
context:
space:
mode:
authorKaloian Manassiev <kaloian.manassiev@mongodb.com>2014-09-26 14:02:49 -0400
committerKaloian Manassiev <kaloian.manassiev@mongodb.com>2014-10-06 17:30:12 -0400
commit101e026f45dea5e9e68520238495c89a476e6172 (patch)
treebbdd3710ffc5721527ad9f5682ef0dbb4876dfee /src/mongo/db/client.h
parent10c86dc6cad9853514148e0ab59894a0d29353b9 (diff)
downloadmongo-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.h83
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();