summaryrefslogtreecommitdiff
path: root/src/mongo/db/db_raii.h
diff options
context:
space:
mode:
authorAndy Schwerin <schwerin@mongodb.com>2015-03-26 16:40:28 -0400
committerAndy Schwerin <schwerin@mongodb.com>2015-03-27 10:25:09 -0400
commit92593d1af174244ba5560be29908b4f729fec78c (patch)
treed98ba6959b2f91da14aad46794248d2323c7ce08 /src/mongo/db/db_raii.h
parent18a3b8528833a478d5a207bfe5fcb8e35673ee8f (diff)
downloadmongo-92593d1af174244ba5560be29908b4f729fec78c.tar.gz
SERVER-17758 Move AutoGet* and Client::*Context to their own file.
The new file is mongo/db/db_raii.h. Also, Client::Context is now OldClientContext and Client::WriteContext is OldClientWriteContext.
Diffstat (limited to 'src/mongo/db/db_raii.h')
-rw-r--r--src/mongo/db/db_raii.h202
1 files changed, 202 insertions, 0 deletions
diff --git a/src/mongo/db/db_raii.h b/src/mongo/db/db_raii.h
new file mode 100644
index 00000000000..580389e9b1b
--- /dev/null
+++ b/src/mongo/db/db_raii.h
@@ -0,0 +1,202 @@
+/**
+ * Copyright (C) 2014 MongoDB Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the GNU Affero General Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+#pragma once
+
+#include <string>
+
+#include "mongo/base/string_data.h"
+#include "mongo/db/catalog/database.h"
+#include "mongo/db/concurrency/d_concurrency.h"
+#include "mongo/db/namespace_string.h"
+#include "mongo/db/operation_context.h"
+#include "mongo/util/timer.h"
+
+namespace mongo {
+
+ class Collection;
+
+ /**
+ * 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.
+ */
+ class AutoGetDb {
+ MONGO_DISALLOW_COPYING(AutoGetDb);
+ public:
+ AutoGetDb(OperationContext* txn, StringData ns, LockMode mode);
+
+ Database* getDb() const {
+ return _db;
+ }
+
+ private:
+ const Lock::DBLock _dbLock;
+ Database* const _db;
+ };
+
+ /**
+ * RAII-style class, which acquires a lock on the specified database in the requested mode and
+ * obtains a reference to the database, creating it was non-existing. Used as a shortcut for
+ * calls to dbHolder().openDb(), taking care of locking details. The requested mode must be
+ * MODE_IX or MODE_X. If the database needs to be created, the lock will automatically be
+ * reacquired as MODE_X.
+ *
+ * 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.
+ */
+ class AutoGetOrCreateDb {
+ MONGO_DISALLOW_COPYING(AutoGetOrCreateDb);
+ public:
+ AutoGetOrCreateDb(OperationContext* txn, StringData ns, LockMode mode);
+
+ Database* getDb() const {
+ return _db;
+ }
+
+ bool justCreated() const {
+ return _justCreated;
+ }
+
+ Lock::DBLock& lock() { return _dbLock; }
+
+ private:
+ ScopedTransaction _transaction;
+ Lock::DBLock _dbLock; // not const, as we may need to relock for implicit create
+ Database* _db;
+ bool _justCreated;
+ };
+
+ /**
+ * 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.
+ */
+ 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.getDb();
+ }
+
+ Collection* getCollection() const {
+ return _coll;
+ }
+
+ private:
+ void _init(const std::string& ns,
+ StringData coll);
+
+ const Timer _timer;
+ OperationContext* const _txn;
+ const ScopedTransaction _transaction;
+ const AutoGetDb _db;
+ const Lock::CollectionLock _collLock;
+
+ Collection* _coll;
+ };
+
+ /**
+ * Opens the database that we want to use and sets the appropriate namespace on the
+ * current operation.
+ */
+ class OldClientContext {
+ MONGO_DISALLOW_COPYING(OldClientContext);
+ public:
+ /** this is probably what you want */
+ OldClientContext(OperationContext* txn, const std::string& ns, bool doVersion = true);
+
+ /**
+ * Below still calls _finishInit, but assumes database has already been acquired
+ * or just created.
+ */
+ OldClientContext(OperationContext* txn,
+ const std::string& ns,
+ Database* db,
+ bool justCreated);
+
+ /**
+ * note: this does not call _finishInit -- i.e., does not call
+ * ensureShardVersionOKOrThrow for example.
+ * see also: reset().
+ */
+ OldClientContext(OperationContext* txn, const std::string& ns, Database * db);
+
+ ~OldClientContext();
+
+ Database* db() const { return _db; }
+ const char* ns() const { return _ns.c_str(); }
+
+ /** @return if the db was created by this OldClientContext */
+ bool justCreated() const { return _justCreated; }
+
+ private:
+ friend class CurOp;
+ void _finishInit();
+ void _checkNotStale() const;
+
+ bool _justCreated;
+ bool _doVersion;
+ const std::string _ns;
+ Database * _db;
+ OperationContext* _txn;
+
+ Timer _timer;
+ };
+
+
+ class OldClientWriteContext {
+ MONGO_DISALLOW_COPYING(OldClientWriteContext);
+ public:
+ OldClientWriteContext(OperationContext* opCtx, const std::string& ns);
+
+ Database* db() const { return _c.db(); }
+
+ Collection* getCollection() const {
+ return _c.db()->getCollection(_nss.ns());
+ }
+
+ private:
+ OperationContext* const _txn;
+ const NamespaceString _nss;
+
+ AutoGetOrCreateDb _autodb;
+ Lock::CollectionLock _collk;
+ OldClientContext _c;
+ Collection* _collection;
+ };
+
+} // namespace mongo