summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mongo/db/SConscript1
-rw-r--r--src/mongo/db/catalog/index_create.cpp3
-rw-r--r--src/mongo/db/clientcursor.cpp8
-rw-r--r--src/mongo/db/clientlistplugin.cpp13
-rw-r--r--src/mongo/db/commands/current_op.cpp9
-rw-r--r--src/mongo/db/commands/getmore_cmd.cpp6
-rw-r--r--src/mongo/db/commands/write_commands/batch_executor.cpp9
-rw-r--r--src/mongo/db/curop.cpp77
-rw-r--r--src/mongo/db/curop.h33
-rw-r--r--src/mongo/db/curop_test.cpp7
-rw-r--r--src/mongo/db/db.cpp2
-rw-r--r--src/mongo/db/dbdirectclient.cpp2
-rw-r--r--src/mongo/db/dbwebserver.cpp2
-rw-r--r--src/mongo/db/index_builder.cpp2
-rw-r--r--src/mongo/db/instance.cpp7
-rw-r--r--src/mongo/db/introspect.cpp1
-rw-r--r--src/mongo/db/operation_context.cpp46
-rw-r--r--src/mongo/db/operation_context.h23
-rw-r--r--src/mongo/db/operation_context_impl.cpp34
-rw-r--r--src/mongo/db/operation_context_impl.h8
-rw-r--r--src/mongo/db/operation_context_noop.h35
-rw-r--r--src/mongo/db/query/find.cpp2
-rw-r--r--src/mongo/db/query/find.h4
-rw-r--r--src/mongo/db/range_deleter.cpp14
-rw-r--r--src/mongo/db/range_deleter_db_env.cpp2
-rw-r--r--src/mongo/db/repl/SConscript1
-rw-r--r--src/mongo/db/repl/bgsync.cpp5
-rw-r--r--src/mongo/db/repl/master_slave.cpp4
-rw-r--r--src/mongo/db/repl/operation_context_repl_mock.cpp25
-rw-r--r--src/mongo/db/repl/operation_context_repl_mock.h11
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl_test.cpp10
-rw-r--r--src/mongo/db/repl/sync_source_feedback.cpp6
-rw-r--r--src/mongo/db/repl/sync_tail.cpp2
-rw-r--r--src/mongo/db/repl/sync_tail_test.cpp14
-rw-r--r--src/mongo/db/service_context.h4
-rw-r--r--src/mongo/db/service_context_d.cpp15
-rw-r--r--src/mongo/db/service_context_d.h2
-rw-r--r--src/mongo/db/service_context_noop.cpp5
-rw-r--r--src/mongo/db/service_context_noop.h2
-rw-r--r--src/mongo/db/storage/SConscript1
-rw-r--r--src/mongo/db/storage/mmap_v1/SConscript4
-rw-r--r--src/mongo/db/storage/mmap_v1/data_file_sync.cpp1
-rw-r--r--src/mongo/dbtests/indexupdatetests.cpp10
-rw-r--r--src/mongo/dbtests/querytests.cpp1
-rw-r--r--src/mongo/dbtests/threadedtests.cpp1
-rw-r--r--src/mongo/s/d_migrate.cpp3
46 files changed, 223 insertions, 254 deletions
diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript
index a8a0567225e..038230f78bb 100644
--- a/src/mongo/db/SConscript
+++ b/src/mongo/db/SConscript
@@ -387,6 +387,7 @@ env.Library(
source=[
'client.cpp',
'client_basic.cpp',
+ 'operation_context.cpp',
'service_context.cpp',
'service_context_noop.cpp',
],
diff --git a/src/mongo/db/catalog/index_create.cpp b/src/mongo/db/catalog/index_create.cpp
index c069b0cc292..3eee9cae3b6 100644
--- a/src/mongo/db/catalog/index_create.cpp
+++ b/src/mongo/db/catalog/index_create.cpp
@@ -42,6 +42,7 @@
#include "mongo/db/audit.h"
#include "mongo/db/background.h"
#include "mongo/db/catalog/collection.h"
+#include "mongo/db/client.h"
#include "mongo/db/clientcursor.h"
#include "mongo/db/concurrency/write_conflict_exception.h"
#include "mongo/db/curop.h"
@@ -228,7 +229,7 @@ namespace mongo {
invariant(_indexes.size() == 1);
invariant(_buildInBackground);
IndexDescriptor* descriptor = _indexes[0].block->getEntry()->descriptor();
- _collection->getIndexCatalog()->registerIndexBuild(descriptor, CurOp::get(_txn)->opNum());
+ _collection->getIndexCatalog()->registerIndexBuild(descriptor, _txn->getOpID());
return descriptor;
}
diff --git a/src/mongo/db/clientcursor.cpp b/src/mongo/db/clientcursor.cpp
index 3a0af5d615f..84fe0017e18 100644
--- a/src/mongo/db/clientcursor.cpp
+++ b/src/mongo/db/clientcursor.cpp
@@ -293,9 +293,11 @@ namespace mongo {
Timer t;
const int Secs = 4;
while (!inShutdown()) {
- OperationContextImpl txn;
- cursorStatsTimedOut.increment(
- CursorManager::timeoutCursorsGlobal(&txn, t.millisReset()));
+ {
+ OperationContextImpl txn;
+ cursorStatsTimedOut.increment(
+ CursorManager::timeoutCursorsGlobal(&txn, t.millisReset()));
+ }
sleepsecs(Secs);
}
}
diff --git a/src/mongo/db/clientlistplugin.cpp b/src/mongo/db/clientlistplugin.cpp
index 89f0f5788f1..6eb854c739d 100644
--- a/src/mongo/db/clientlistplugin.cpp
+++ b/src/mongo/db/clientlistplugin.cpp
@@ -101,8 +101,8 @@ namespace {
ss << "<tr><td>" << client->desc() << "</td>";
- tablecell(ss, curOp->opNum());
- tablecell(ss, curOp->active());
+ tablecell(ss, txn->getOpID());
+ tablecell(ss, true);
// LockState
{
@@ -115,12 +115,7 @@ namespace {
tablecell(ss, lockerInfoBuilder.obj());
}
- if (curOp->active()) {
- tablecell(ss, curOp->elapsedSeconds());
- }
- else {
- tablecell(ss, "");
- }
+ tablecell(ss, curOp->elapsedSeconds());
tablecell(ss, curOp->getOp());
tablecell(ss, html::escape(curOp->getNS()));
@@ -210,7 +205,9 @@ namespace {
client->reportState(b);
const OperationContext* txn = client->getOperationContext();
+ b.appendBool("active", static_cast<bool>(txn));
if (txn) {
+ b.append("opid", txn->getOpID());
// CurOp
if (CurOp::get(txn)) {
diff --git a/src/mongo/db/commands/current_op.cpp b/src/mongo/db/commands/current_op.cpp
index 402558814df..b26c811d2d8 100644
--- a/src/mongo/db/commands/current_op.cpp
+++ b/src/mongo/db/commands/current_op.cpp
@@ -113,9 +113,6 @@ namespace mongo {
// Skip over inactive connections.
if (!opCtx)
continue;
- auto curOp = CurOp::get(opCtx);
- if (!curOp || !curOp->active())
- continue;
}
BSONObjBuilder infoBuilder;
@@ -124,7 +121,9 @@ namespace mongo {
client->reportState(infoBuilder);
// Operation context specific information
+ infoBuilder.appendBool("active", static_cast<bool>(opCtx));
if (opCtx) {
+ infoBuilder.append("opid", opCtx->getOpID());
// CurOp
if (CurOp::get(opCtx)) {
CurOp::get(opCtx)->reportState(&infoBuilder);
@@ -135,10 +134,6 @@ namespace mongo {
opCtx->lockState()->getLockerInfo(&lockerInfo);
fillLockerInfo(lockerInfo, infoBuilder);
}
- else {
- // If no operation context, mark the operation as inactive
- infoBuilder.append("active", false);
- }
infoBuilder.done();
diff --git a/src/mongo/db/commands/getmore_cmd.cpp b/src/mongo/db/commands/getmore_cmd.cpp
index 2fad5d8917b..bc2bf72328e 100644
--- a/src/mongo/db/commands/getmore_cmd.cpp
+++ b/src/mongo/db/commands/getmore_cmd.cpp
@@ -37,16 +37,20 @@
#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/catalog/collection.h"
#include "mongo/db/catalog/cursor_manager.h"
+#include "mongo/db/client.h"
#include "mongo/db/clientcursor.h"
#include "mongo/db/commands.h"
+#include "mongo/db/curop.h"
#include "mongo/db/db_raii.h"
#include "mongo/db/exec/working_set_common.h"
#include "mongo/db/global_timestamp.h"
+#include "mongo/db/query/cursor_responses.h"
#include "mongo/db/repl/oplog.h"
#include "mongo/db/service_context.h"
-#include "mongo/db/query/cursor_responses.h"
#include "mongo/db/query/find.h"
#include "mongo/db/query/getmore_request.h"
+#include "mongo/db/repl/oplog.h"
+#include "mongo/db/service_context.h"
#include "mongo/db/stats/counters.h"
#include "mongo/util/log.h"
#include "mongo/util/scopeguard.h"
diff --git a/src/mongo/db/commands/write_commands/batch_executor.cpp b/src/mongo/db/commands/write_commands/batch_executor.cpp
index c698c352e50..3d3ca64cfb1 100644
--- a/src/mongo/db/commands/write_commands/batch_executor.cpp
+++ b/src/mongo/db/commands/write_commands/batch_executor.cpp
@@ -896,7 +896,8 @@ namespace mongo {
WriteErrorDetail** error ) {
// BEGIN CURRENT OP
- CurOp currentOp(_txn->getClient(), dbUpdate);
+ CurOp currentOp(_txn);
+ currentOp.setOp(dbUpdate);
beginCurrentOp( &currentOp, _txn->getClient(), updateItem );
incOpStats( updateItem );
@@ -940,7 +941,8 @@ namespace mongo {
// Removes are similar to updates, but page faults are handled externally
// BEGIN CURRENT OP
- CurOp currentOp(_txn->getClient(), dbDelete);
+ CurOp currentOp(_txn);
+ currentOp.setOp(dbDelete);
beginCurrentOp( &currentOp, _txn->getClient(), removeItem );
incOpStats( removeItem );
@@ -1135,7 +1137,8 @@ namespace mongo {
void WriteBatchExecutor::execOneInsert(ExecInsertsState* state, WriteErrorDetail** error) {
BatchItemRef currInsertItem(state->request, state->currIndex);
- CurOp currentOp(_txn->getClient(), dbInsert);
+ CurOp currentOp(_txn);
+ currentOp.setOp(dbInsert);
beginCurrentOp( &currentOp, _txn->getClient(), currInsertItem );
incOpStats(currInsertItem);
diff --git a/src/mongo/db/curop.cpp b/src/mongo/db/curop.cpp
index 640c82063e0..4c41b5bd365 100644
--- a/src/mongo/db/curop.cpp
+++ b/src/mongo/db/curop.cpp
@@ -56,10 +56,10 @@ namespace mongo {
*
* The stack itself is represented in the _parent pointers of the CurOp class.
*/
- class CurOp::ClientCuropStack {
- MONGO_DISALLOW_COPYING(ClientCuropStack);
+ class CurOp::CurOpStack {
+ MONGO_DISALLOW_COPYING(CurOpStack);
public:
- ClientCuropStack() : _base(nullptr, this) {}
+ CurOpStack() : _base(nullptr, this) {}
/**
* Returns the top of the CurOp stack.
@@ -69,15 +69,15 @@ namespace mongo {
/**
* Adds "curOp" to the top of the CurOp stack for a client. Called by CurOp's constructor.
*/
- void push(Client* client, CurOp* curOp) {
- invariant(client);
- if (_client) {
- invariant(_client == client);
+ void push(OperationContext* opCtx, CurOp* curOp) {
+ invariant(opCtx);
+ if (_opCtx) {
+ invariant(_opCtx == opCtx);
}
else {
- _client = client;
+ _opCtx = opCtx;
}
- boost::lock_guard<Client> lk(*_client);
+ boost::lock_guard<Client> lk(*_opCtx->getClient());
push_nolock(curOp);
}
@@ -101,20 +101,20 @@ namespace mongo {
// the client during the final pop.
const bool shouldLock = _top->_parent;
if (shouldLock) {
- invariant(_client);
- _client->lock();
+ invariant(_opCtx);
+ _opCtx->getClient()->lock();
}
invariant(_top);
CurOp* retval = _top;
_top = _top->_parent;
if (shouldLock) {
- _client->unlock();
+ _opCtx->getClient()->unlock();
}
return retval;
}
private:
- Client* _client = nullptr;
+ OperationContext* _opCtx = nullptr;
// Top of the stack of CurOps for a Client.
CurOp* _top = nullptr;
@@ -123,8 +123,8 @@ namespace mongo {
const CurOp _base;
};
- const Client::Decoration<CurOp::ClientCuropStack> CurOp::_curopStack =
- Client::declareDecoration<CurOp::ClientCuropStack>();
+ const OperationContext::Decoration<CurOp::CurOpStack> CurOp::_curopStack =
+ OperationContext::declareDecoration<CurOp::CurOpStack>();
// Enabling the maxTimeAlwaysTimeOut fail point will cause any query or command run with a
// valid non-zero max time to fail immediately. Any getmore operation on a cursor already
@@ -146,33 +146,18 @@ namespace mongo {
CurOp* CurOp::get(const OperationContext* opCtx) { return get(*opCtx); }
- CurOp* CurOp::get(const OperationContext& opCtx) {
- return _curopStack(opCtx.getClient()).top();
- }
+ CurOp* CurOp::get(const OperationContext& opCtx) { return _curopStack(opCtx).top(); }
- CurOp::CurOp(Client* client) : CurOp(client, &_curopStack(client)) {}
+ CurOp::CurOp(OperationContext* opCtx) : CurOp(opCtx, &_curopStack(opCtx)) {}
- CurOp::CurOp(Client* client, ClientCuropStack* stack) : _stack(stack) {
- if (client) {
- _stack->push(client, this);
+ CurOp::CurOp(OperationContext* opCtx, CurOpStack* stack) : _stack(stack) {
+ if (opCtx) {
+ _stack->push(opCtx, this);
}
else {
_stack->push_nolock(this);
}
_start = 0;
- _active = false;
- _reset();
- _op = 0;
- _opNum = _nextOpNum.fetchAndAdd(1);
- _command = NULL;
- }
-
- CurOp::CurOp(Client* client, int op) : CurOp(client, &_curopStack(client)) {
- _op = op;
- _active = true;
- }
-
- void CurOp::_reset() {
_isCommand = false;
_dbprofile = 0;
_end = 0;
@@ -183,20 +168,11 @@ namespace mongo {
_killPending.store(0);
_numYields = 0;
_expectedLatencyMs = 0;
+ _op = 0;
+ _command = NULL;
}
- void CurOp::reset() {
- _reset();
- _start = 0;
- _opNum = _nextOpNum.fetchAndAdd(1);
- _ns = "";
- _debug.reset();
- _query.reset();
- _active = true; // this should be last for ui clarity
- }
-
- void CurOp::reset(int op) {
- reset();
+ void CurOp::setOp(int op) {
_op = op;
}
@@ -254,11 +230,8 @@ namespace mongo {
}
void CurOp::reportState(BSONObjBuilder* builder) {
- builder->append("opid", _opNum);
- bool a = _active && _start;
- builder->append("active", a);
- if( a ) {
+ if (_start) {
builder->append("secs_running", elapsedSeconds() );
builder->append("microsecs_running", static_cast<long long int>(elapsedMicros()) );
}
@@ -412,8 +385,6 @@ namespace mongo {
}
- AtomicUInt32 CurOp::_nextOpNum;
-
static Counter64 returnedCounter;
static Counter64 insertedCounter;
static Counter64 updatedCounter;
diff --git a/src/mongo/db/curop.h b/src/mongo/db/curop.h
index 66201f53fdd..f58ee576370 100644
--- a/src/mongo/db/curop.h
+++ b/src/mongo/db/curop.h
@@ -34,7 +34,7 @@
#include <boost/noncopyable.hpp>
#include "mongo/base/disallow_copying.h"
-#include "mongo/db/client.h"
+#include "mongo/db/operation_context.h"
#include "mongo/db/server_options.h"
#include "mongo/platform/atomic_word.h"
#include "mongo/util/concurrency/spin_lock.h"
@@ -198,8 +198,7 @@ namespace mongo {
static CurOp* get(const OperationContext* opCtx);
static CurOp* get(const OperationContext& opCtx);
- explicit CurOp(Client* client);
- CurOp(Client* client, int op);
+ explicit CurOp(OperationContext* client);
~CurOp();
bool haveQuery() const { return _query.have(); }
@@ -207,8 +206,11 @@ namespace mongo {
void appendQuery( BSONObjBuilder& b , StringData name ) const { _query.append( b , name ); }
void enter(const char* ns, int dbProfileLevel);
- void reset();
- void reset(int op);
+
+ /**
+ * Sets the type of the current operation to "op".
+ */
+ void setOp(int op);
void markCommand() { _isCommand = true; }
OpDebug& debug() { return _debug; }
std::string getNS() const { return _ns.toString(); }
@@ -220,11 +222,6 @@ namespace mongo {
return _dbprofile >= 2 || ms >= serverGlobalParams.slowMS;
}
- unsigned int opNum() const { return _opNum; }
-
- /** if this op is running */
- bool active() const { return _active; }
-
int getOp() const { return _op; }
//
@@ -271,12 +268,11 @@ namespace mongo {
return _start;
}
void done() {
- _active = false;
_end = curTimeMicros64();
}
long long totalTimeMicros() {
- massert( 12601 , "CurOp not marked done yet" , ! _active );
+ massert( 12601 , "CurOp not marked done yet" , _end );
return _end - startTime();
}
int totalTimeMillis() { return (int) (totalTimeMicros() / 1000); }
@@ -321,25 +317,20 @@ namespace mongo {
void setNS( StringData ns );
private:
- class ClientCuropStack;
-
- static const Client::Decoration<ClientCuropStack> _curopStack;
+ class CurOpStack;
- CurOp(Client*, ClientCuropStack*);
+ static const OperationContext::Decoration<CurOpStack> _curopStack;
- void _reset();
+ CurOp(OperationContext*, CurOpStack*);
- static AtomicUInt32 _nextOpNum;
- ClientCuropStack* _stack;
+ CurOpStack* _stack;
CurOp* _parent = nullptr;
Command * _command;
long long _start;
long long _end;
- bool _active;
int _op;
bool _isCommand;
int _dbprofile; // 0=off, 1=slow, 2=all
- unsigned int _opNum;
ThreadSafeString _ns;
CachedBSONObj<512> _query; // CachedBSONObj is thread safe
OpDebug _debug;
diff --git a/src/mongo/db/curop_test.cpp b/src/mongo/db/curop_test.cpp
index 17ac612c3a3..1f4f58153eb 100644
--- a/src/mongo/db/curop_test.cpp
+++ b/src/mongo/db/curop_test.cpp
@@ -33,6 +33,7 @@
#include "mongo/base/init.h"
#include "mongo/db/client.h"
#include "mongo/db/curop.h"
+#include "mongo/db/operation_context_noop.h"
#include "mongo/db/service_context.h"
#include "mongo/db/service_context_noop.h"
#include "mongo/stdx/memory.h"
@@ -77,7 +78,8 @@ namespace mongo {
TEST(TimeHasExpired, PosSimple) {
auto service = stdx::make_unique<ServiceContextNoop>();
auto client = service->makeClient("CurOpTest");
- CurOp curOp(client.get());
+ OperationContextNoop txn(client.get(), 100);
+ CurOp curOp(&txn);
curOp.setMaxTimeMicros(intervalShort);
curOp.ensureStarted();
sleepmicros(intervalLong);
@@ -88,7 +90,8 @@ namespace mongo {
TEST(TimeHasExpired, NegSimple) {
auto service = stdx::make_unique<ServiceContextNoop>();
auto client = service->makeClient("CurOpTest");
- CurOp curOp(client.get());
+ OperationContextNoop txn(client.get(), 100);
+ CurOp curOp(&txn);
curOp.setMaxTimeMicros(intervalLong);
curOp.ensureStarted();
sleepmicros(intervalShort);
diff --git a/src/mongo/db/db.cpp b/src/mongo/db/db.cpp
index d7e69a0c5ca..61678070dcf 100644
--- a/src/mongo/db/db.cpp
+++ b/src/mongo/db/db.cpp
@@ -157,13 +157,13 @@ namespace mongo {
}
virtual void process(Message& m , AbstractMessagingPort* port) {
- OperationContextImpl txn;
while ( true ) {
if ( inShutdown() ) {
log() << "got request after shutdown()" << endl;
break;
}
+ OperationContextImpl txn;
DbResponse dbresponse;
assembleResponse(&txn, m, dbresponse, port->remote());
diff --git a/src/mongo/db/dbdirectclient.cpp b/src/mongo/db/dbdirectclient.cpp
index 3aee1750172..f0107baf9ce 100644
--- a/src/mongo/db/dbdirectclient.cpp
+++ b/src/mongo/db/dbdirectclient.cpp
@@ -126,6 +126,7 @@ namespace mongo {
LastError::get(_txn->getClient()).startRequest();
DbResponse dbResponse;
+ CurOp curOp(_txn);
assembleResponse(_txn, toSend, dbResponse, dummyHost);
verify(dbResponse.response);
@@ -141,6 +142,7 @@ namespace mongo {
LastError::get(_txn->getClient()).startRequest();
DbResponse dbResponse;
+ CurOp curOp(_txn);
assembleResponse(_txn, toSend, dbResponse, dummyHost);
}
diff --git a/src/mongo/db/dbwebserver.cpp b/src/mongo/db/dbwebserver.cpp
index ed5bf9f2192..bd12f09e255 100644
--- a/src/mongo/db/dbwebserver.cpp
+++ b/src/mongo/db/dbwebserver.cpp
@@ -314,7 +314,7 @@ namespace {
vector<string>& headers,
const SockAddr &from) {
- boost::scoped_ptr<OperationContext> txn(getGlobalServiceContext()->newOpCtx());
+ auto txn = getGlobalServiceContext()->newOpCtx();
if (url.size() > 1) {
diff --git a/src/mongo/db/index_builder.cpp b/src/mongo/db/index_builder.cpp
index 7baf390792d..45620ee0544 100644
--- a/src/mongo/db/index_builder.cpp
+++ b/src/mongo/db/index_builder.cpp
@@ -87,7 +87,7 @@ namespace {
AuthorizationSession::get(txn.getClient())->grantInternalAuthorization();
- CurOp::get(txn)->reset(dbInsert);
+ CurOp::get(txn)->setOp(dbInsert);
NamespaceString ns(_index["ns"].String());
ScopedTransaction transaction(&txn, MODE_IX);
diff --git a/src/mongo/db/instance.cpp b/src/mongo/db/instance.cpp
index f5399564d6e..c1927347377 100644
--- a/src/mongo/db/instance.cpp
+++ b/src/mongo/db/instance.cpp
@@ -516,13 +516,8 @@ namespace {
break;
}
- scoped_ptr<CurOp> nestedOp;
- if (CurOp::get(txn)->active()) {
- nestedOp.reset(new CurOp(&c));
- }
-
CurOp& currentOp = *CurOp::get(txn);
- currentOp.reset(op);
+ currentOp.setOp(op);
OpDebug& debug = currentOp.debug();
debug.op = op;
diff --git a/src/mongo/db/introspect.cpp b/src/mongo/db/introspect.cpp
index 1f6e0003e6c..9354f8cd3ca 100644
--- a/src/mongo/db/introspect.cpp
+++ b/src/mongo/db/introspect.cpp
@@ -37,6 +37,7 @@
#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/auth/user_set.h"
#include "mongo/db/catalog/collection.h"
+#include "mongo/db/client.h"
#include "mongo/db/curop.h"
#include "mongo/db/db_raii.h"
#include "mongo/db/jsobj.h"
diff --git a/src/mongo/db/operation_context.cpp b/src/mongo/db/operation_context.cpp
new file mode 100644
index 00000000000..5c87bee7220
--- /dev/null
+++ b/src/mongo/db/operation_context.cpp
@@ -0,0 +1,46 @@
+/**
+ * Copyright (C) 2015 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.
+ */
+
+#include "mongo/platform/basic.h"
+
+#include "mongo/db/operation_context.h"
+
+#include "mongo/util/assert_util.h"
+
+namespace mongo {
+
+ OperationContext::OperationContext(Client* client, unsigned int opId, Locker* locker) :
+ _client(client), _opId(opId), _locker(locker) {
+ }
+
+ Client* OperationContext::getClient() const {
+ invariant(_client);
+ return _client;
+ }
+
+} // namespace mongo
diff --git a/src/mongo/db/operation_context.h b/src/mongo/db/operation_context.h
index 0717745e858..e3c28ef2c05 100644
--- a/src/mongo/db/operation_context.h
+++ b/src/mongo/db/operation_context.h
@@ -31,7 +31,6 @@
#include "mongo/base/disallow_copying.h"
#include "mongo/base/status.h"
#include "mongo/db/storage/recovery_unit.h"
-#include "mongo/db/concurrency/locker.h"
#include "mongo/db/concurrency/d_concurrency.h"
#include "mongo/db/write_concern_options.h"
#include "mongo/util/decorable.h"
@@ -40,6 +39,7 @@ namespace mongo {
class Client;
class CurOp;
+ class Locker;
class ProgressMeter;
class StringData;
class WriteUnitOfWork;
@@ -68,7 +68,7 @@ namespace mongo {
kFailedUnitOfWork // in a unit of work that has failed and must be aborted
};
- virtual ~OperationContext() { }
+ virtual ~OperationContext() = default;
/**
* Interface for durability. Caller DOES NOT own pointer.
@@ -101,7 +101,7 @@ namespace mongo {
/**
* Interface for locking. Caller DOES NOT own pointer.
*/
- virtual Locker* lockState() const = 0;
+ Locker* lockState() const { return _locker; }
// --- operation level info? ---
@@ -132,16 +132,14 @@ namespace mongo {
/**
* Returns the client under which this context runs.
*/
- virtual Client* getClient() const = 0;
+ Client* getClient() const;
virtual uint64_t getRemainingMaxTimeMicros() const = 0;
/**
* Returns the operation ID associated with this operation.
- * WARNING: Due to SERVER-14995, this OpID is not guaranteed to stay the same for the
- * lifetime of this OperationContext.
*/
- virtual unsigned int getOpID() const = 0;
+ unsigned int getOpID() const { return _opId; }
/**
* @return true if this instance is primary for this namespace
@@ -170,12 +168,21 @@ namespace mongo {
virtual bool writesAreReplicated() const = 0;
protected:
- OperationContext() { }
+ OperationContext(Client* client,
+ unsigned int opId,
+ Locker* locker);
RecoveryUnitState _ruState = kNotInUnitOfWork;
private:
friend class WriteUnitOfWork;
+ Client* const _client;
+ const unsigned int _opId;
+
+ // The lifetime of locker is managed by subclasses of OperationContext, so it is not
+ // safe to access _locker in the destructor of OperationContext.
+ Locker* const _locker;
+
WriteConcernOptions _writeConcern;
};
diff --git a/src/mongo/db/operation_context_impl.cpp b/src/mongo/db/operation_context_impl.cpp
index b57090e04b9..6eccefce706 100644
--- a/src/mongo/db/operation_context_impl.cpp
+++ b/src/mongo/db/operation_context_impl.cpp
@@ -69,28 +69,30 @@ namespace {
const auto clientOperationInfoDecoration = Client::declareDecoration<ClientOperationInfo>();
+ AtomicUInt32 nextOpId{1};
} // namespace
using std::string;
OperationContextImpl::OperationContextImpl()
- : _client(&cc()),
- _locker(clientOperationInfoDecoration(_client).getLocker()),
+ : OperationContext(&cc(),
+ nextOpId.fetchAndAdd(1),
+ clientOperationInfoDecoration(cc()).getLocker()),
_writesAreReplicated(true) {
- invariant(_locker);
-
StorageEngine* storageEngine = getGlobalServiceContext()->getGlobalStorageEngine();
_recovery.reset(storageEngine->newRecoveryUnit());
- stdx::lock_guard<Client> lk(*_client);
- _client->setOperationContext(this);
+ auto client = getClient();
+ stdx::lock_guard<Client> lk(*client);
+ client->setOperationContext(this);
}
OperationContextImpl::~OperationContextImpl() {
- _locker->assertEmptyAndReset();
- stdx::lock_guard<Client> lk(*_client);
- _client->resetOperationContext();
+ lockState()->assertEmptyAndReset();
+ auto client = getClient();
+ stdx::lock_guard<Client> lk(*client);
+ client->resetOperationContext();
}
RecoveryUnit* OperationContextImpl::recoveryUnit() const {
@@ -113,10 +115,6 @@ namespace {
return oldState;
}
- Locker* OperationContextImpl::lockState() const {
- return _locker;
- }
-
ProgressMeter* OperationContextImpl::setMessage(const char * msg,
const std::string &name,
unsigned long long progressMeterTotal,
@@ -128,14 +126,6 @@ namespace {
return CurOp::get(this)->getNS();
}
- Client* OperationContextImpl::getClient() const {
- return _client;
- }
-
- unsigned int OperationContextImpl::getOpID() const {
- return CurOp::get(this)->opNum();
- }
-
uint64_t OperationContextImpl::getRemainingMaxTimeMicros() const {
return CurOp::get(this)->getRemainingMaxTimeMicros();
}
@@ -208,7 +198,7 @@ namespace {
if (opShouldFail(this, scopedFailPoint.getData())) {
log() << "set pending kill on "
<< (curOp->parent() ? "nested" : "top-level")
- << " op " << curOp->opNum() << ", for checkForInterruptFail";
+ << " op " << getOpID() << ", for checkForInterruptFail";
curOp->kill();
}
}
diff --git a/src/mongo/db/operation_context_impl.h b/src/mongo/db/operation_context_impl.h
index a904400648a..362455581fd 100644
--- a/src/mongo/db/operation_context_impl.h
+++ b/src/mongo/db/operation_context_impl.h
@@ -47,8 +47,6 @@ namespace mongo {
virtual RecoveryUnitState setRecoveryUnit(RecoveryUnit* unit,
RecoveryUnitState state) override;
- virtual Locker* lockState() const override;
-
virtual ProgressMeter* setMessage(const char* msg,
const std::string& name,
unsigned long long progressMeterTotal,
@@ -56,10 +54,6 @@ namespace mongo {
virtual std::string getNS() const override;
- virtual Client* getClient() const override;
-
- virtual unsigned int getOpID() const override;
-
virtual uint64_t getRemainingMaxTimeMicros() const override;
virtual void checkForInterrupt() const override;
@@ -72,8 +66,6 @@ namespace mongo {
private:
std::auto_ptr<RecoveryUnit> _recovery;
- Client* const _client; // cached, not owned
- Locker* const _locker; // cached, not owned
bool _writesAreReplicated;
};
diff --git a/src/mongo/db/operation_context_noop.h b/src/mongo/db/operation_context_noop.h
index a428042438c..254f553445b 100644
--- a/src/mongo/db/operation_context_noop.h
+++ b/src/mongo/db/operation_context_noop.h
@@ -39,25 +39,32 @@ namespace mongo {
class OperationContextNoop : public OperationContext {
public:
- OperationContextNoop(RecoveryUnit* ru)
- : _recoveryUnit(ru),
- _locker(new LockerNoop()) {
+ OperationContextNoop() : OperationContextNoop(new RecoveryUnitNoop()) {}
+
+ OperationContextNoop(RecoveryUnit* ru) : OperationContextNoop(nullptr, 0, ru) {}
+
+ OperationContextNoop(Client* client, unsigned int opId)
+ : OperationContextNoop(client, opId, new RecoveryUnitNoop()) {
}
- OperationContextNoop()
- : _recoveryUnit(new RecoveryUnitNoop()),
- _locker(new LockerNoop()) {
+ OperationContextNoop(Client* client, unsigned int opId, RecoveryUnit* ru)
+ : OperationContextNoop(client, opId, new LockerNoop(), ru) {
+ }
+ OperationContextNoop(Client* client, unsigned int opId, Locker* locker)
+ : OperationContextNoop(client, opId, locker, new RecoveryUnitNoop()) {
}
- virtual ~OperationContextNoop() { }
+ OperationContextNoop(Client* client, unsigned int opId, Locker* locker, RecoveryUnit* ru)
+ : OperationContext(client, opId, locker),
+ _recoveryUnit(ru) {
- virtual Client* getClient() const override {
- invariant(false);
- return NULL;
+ _locker.reset(lockState());
}
+ virtual ~OperationContextNoop() = default;
+
virtual RecoveryUnit* recoveryUnit() const override {
return _recoveryUnit.get();
}
@@ -74,10 +81,6 @@ namespace mongo {
return oldState;
}
- virtual Locker* lockState() const override {
- return _locker.get();
- }
-
virtual ProgressMeter* setMessage(const char * msg,
const std::string &name,
unsigned long long progressMeterTotal,
@@ -98,10 +101,6 @@ namespace mongo {
return std::string();
};
- virtual unsigned int getOpID() const override {
- return 0;
- }
-
void setReplicatedWrites(bool writesAreReplicated = true) override {}
bool writesAreReplicated() const override {
diff --git a/src/mongo/db/query/find.cpp b/src/mongo/db/query/find.cpp
index c1938e51852..eb2b62f8d4a 100644
--- a/src/mongo/db/query/find.cpp
+++ b/src/mongo/db/query/find.cpp
@@ -37,8 +37,10 @@
#include "mongo/client/dbclientinterface.h"
#include "mongo/db/catalog/collection.h"
#include "mongo/db/catalog/database_holder.h"
+#include "mongo/db/client.h"
#include "mongo/db/clientcursor.h"
#include "mongo/db/commands.h"
+#include "mongo/db/curop.h"
#include "mongo/db/db_raii.h"
#include "mongo/db/exec/filter.h"
#include "mongo/db/exec/working_set_common.h"
diff --git a/src/mongo/db/query/find.h b/src/mongo/db/query/find.h
index 876070a5fdc..650a6f0e4fd 100644
--- a/src/mongo/db/query/find.h
+++ b/src/mongo/db/query/find.h
@@ -31,13 +31,15 @@
#include <string>
#include "mongo/db/clientcursor.h"
-#include "mongo/db/curop.h"
#include "mongo/db/dbmessage.h"
+#include "mongo/db/operation_context.h"
#include "mongo/db/query/canonical_query.h"
#include "mongo/util/net/message.h"
namespace mongo {
+ class CurOp;
+ class NamespaceString;
class OperationContext;
class ScopedRecoveryUnitSwapper {
diff --git a/src/mongo/db/range_deleter.cpp b/src/mongo/db/range_deleter.cpp
index caa2c63804c..cb00ad28554 100644
--- a/src/mongo/db/range_deleter.cpp
+++ b/src/mongo/db/range_deleter.cpp
@@ -448,8 +448,6 @@ namespace {
while (!inShutdown() && !stopRequested()) {
string errMsg;
- boost::scoped_ptr<OperationContext> txn(getGlobalServiceContext()->newOpCtx());
-
RangeDeleteEntry* nextTask = NULL;
{
@@ -472,12 +470,11 @@ namespace {
RangeDeleteEntry* entry = *iter;
set<CursorId> cursorsNow;
- {
- if (entry->options.waitForOpenCursors) {
- _env->getCursorIds(txn.get(),
- entry->options.range.ns,
- &cursorsNow);
- }
+ if (entry->options.waitForOpenCursors) {
+ auto txn = getGlobalServiceContext()->newOpCtx();
+ _env->getCursorIds(txn.get(),
+ entry->options.range.ns,
+ &cursorsNow);
}
set<CursorId> cursorsLeft;
@@ -516,6 +513,7 @@ namespace {
}
{
+ auto txn = getGlobalServiceContext()->newOpCtx();
nextTask->stats.deleteStartTS = jsTime();
bool delResult = _env->deleteRange(txn.get(),
*nextTask,
diff --git a/src/mongo/db/range_deleter_db_env.cpp b/src/mongo/db/range_deleter_db_env.cpp
index a73c1070ca7..c84818158c2 100644
--- a/src/mongo/db/range_deleter_db_env.cpp
+++ b/src/mongo/db/range_deleter_db_env.cpp
@@ -90,7 +90,7 @@ namespace mongo {
}
// log the opId so the user can use it to cancel the delete using killOp.
- unsigned int opId = CurOp::get(txn)->opNum();
+ unsigned int opId = txn->getOpID();
log() << "Deleter starting delete for: " << ns
<< " from " << inclusiveLower
<< " -> " << exclusiveUpper
diff --git a/src/mongo/db/repl/SConscript b/src/mongo/db/repl/SConscript
index 8cf92b22702..146039a94cf 100644
--- a/src/mongo/db/repl/SConscript
+++ b/src/mongo/db/repl/SConscript
@@ -538,6 +538,7 @@ env.Library(
],
LIBDEPS=[
'task_runner',
+ '$BUILD_DIR/mongo/db/service_context',
'$BUILD_DIR/mongo/unittest/concurrency',
'$BUILD_DIR/mongo/util/decorable',
],
diff --git a/src/mongo/db/repl/bgsync.cpp b/src/mongo/db/repl/bgsync.cpp
index 29ad6d5704f..a9c5e068bc7 100644
--- a/src/mongo/db/repl/bgsync.cpp
+++ b/src/mongo/db/repl/bgsync.cpp
@@ -187,8 +187,6 @@ namespace {
return;
}
- OperationContextImpl txn;
-
// We need to wait until initial sync has started.
if (_replCoord->getMyLastOptime().isNull()) {
sleepsecs(1);
@@ -196,7 +194,8 @@ namespace {
}
// we want to unpause when we're no longer primary
// start() also loads _lastOpTimeFetched, which we know is set from the "if"
- else if (_pause) {
+ OperationContextImpl txn;
+ if (_pause) {
start(&txn);
}
diff --git a/src/mongo/db/repl/master_slave.cpp b/src/mongo/db/repl/master_slave.cpp
index dc975fe7b90..fde2c24232c 100644
--- a/src/mongo/db/repl/master_slave.cpp
+++ b/src/mongo/db/repl/master_slave.cpp
@@ -695,6 +695,9 @@ namespace repl {
if ( !only.empty() && only != clientName )
return;
+ // Push the CurOp stack for "txn" so each individual oplog entry application is separately
+ // reported.
+ CurOp individualOp(txn);
txn->setReplicatedWrites(false);
const ReplSettings& replSettings = getGlobalReplicationCoordinator()->getSettings();
if (replSettings.pretouch &&
@@ -757,7 +760,6 @@ namespace repl {
// mongos will not send requests there. That's why the last argument is false (do not do
// version checking).
OldClientContext ctx(txn, ns, false);
- CurOp::get(txn)->reset();
bool empty = !ctx.db()->getDatabaseCatalogEntry()->hasUserData();
bool incompleteClone = incompleteCloneDbs.count( clientName ) != 0;
diff --git a/src/mongo/db/repl/operation_context_repl_mock.cpp b/src/mongo/db/repl/operation_context_repl_mock.cpp
index 5cfc9f31713..10d2e69beca 100644
--- a/src/mongo/db/repl/operation_context_repl_mock.cpp
+++ b/src/mongo/db/repl/operation_context_repl_mock.cpp
@@ -36,27 +36,20 @@
namespace mongo {
namespace repl {
- OperationContextReplMock::OperationContextReplMock():
- _lockState(new MMAPV1LockerImpl()),
- _opID(0),
- _checkForInterruptStatus(Status::OK()),
- _maxTimeMicrosRemaining(0),
- _writesAreReplicated(true) {
- }
-
- OperationContextReplMock::~OperationContextReplMock() {}
+ OperationContextReplMock::OperationContextReplMock() : OperationContextReplMock(0) {}
- Locker* OperationContextReplMock::lockState() const {
- return _lockState.get();
+ OperationContextReplMock::OperationContextReplMock(unsigned int opNum) :
+ OperationContextReplMock(nullptr, opNum) {
}
- unsigned int OperationContextReplMock::getOpID() const {
- return _opID;
+ OperationContextReplMock::OperationContextReplMock(Client* client, unsigned int opNum) :
+ OperationContextNoop(client, opNum, new MMAPV1LockerImpl()),
+ _checkForInterruptStatus(Status::OK()),
+ _maxTimeMicrosRemaining(0),
+ _writesAreReplicated(true) {
}
- void OperationContextReplMock::setOpID(unsigned int opID) {
- _opID = opID;
- }
+ OperationContextReplMock::~OperationContextReplMock() = default;
void OperationContextReplMock::checkForInterrupt() const {
uassertStatusOK(checkForInterruptNoAssert());
diff --git a/src/mongo/db/repl/operation_context_repl_mock.h b/src/mongo/db/repl/operation_context_repl_mock.h
index 6efacdaa68d..6c5e76b046f 100644
--- a/src/mongo/db/repl/operation_context_repl_mock.h
+++ b/src/mongo/db/repl/operation_context_repl_mock.h
@@ -46,14 +46,10 @@ namespace repl {
class OperationContextReplMock : public OperationContextNoop {
public:
OperationContextReplMock();
+ explicit OperationContextReplMock(unsigned int opNum);
+ OperationContextReplMock(Client* client, unsigned int opNum);
virtual ~OperationContextReplMock();
- virtual Locker* lockState() const override;
-
- virtual unsigned int getOpID() const override;
-
- void setOpID(unsigned int opID);
-
virtual void checkForInterrupt() const override;
virtual Status checkForInterruptNoAssert() const override;
@@ -69,9 +65,6 @@ namespace repl {
bool writesAreReplicated() const override;
private:
- boost::scoped_ptr<Locker> _lockState;
- unsigned int _opID;
-
Status _checkForInterruptStatus;
uint64_t _maxTimeMicrosRemaining;
bool _writesAreReplicated;
diff --git a/src/mongo/db/repl/replication_coordinator_impl_test.cpp b/src/mongo/db/repl/replication_coordinator_impl_test.cpp
index 5ced40ce853..3f5a574d0e4 100644
--- a/src/mongo/db/repl/replication_coordinator_impl_test.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl_test.cpp
@@ -857,7 +857,8 @@ namespace {
TEST_F(ReplCoordTest, AwaitReplicationInterrupt) {
// Tests that a thread blocked in awaitReplication can be killed by a killOp operation
- OperationContextReplMock txn;
+ const unsigned int opID = 100;
+ OperationContextReplMock txn{opID};
assertStartSuccess(
BSON("_id" << "mySet" <<
"version" << 2 <<
@@ -878,8 +879,6 @@ namespace {
writeConcern.wTimeout = WriteConcernOptions::kNoTimeout;
writeConcern.wNumNodes = 2;
- unsigned int opID = 100;
- txn.setOpID(opID);
// 2 nodes waiting for time2
awaiter.setOpTime(time2);
@@ -1215,7 +1214,8 @@ namespace {
}
TEST_F(StepDownTest, InterruptStepDown) {
- OperationContextReplMock txn;
+ const unsigned int opID = 100;
+ OperationContextReplMock txn{opID};
OpTimeWithTermZero optime1(100, 1);
OpTimeWithTermZero optime2(100, 2);
// No secondary is caught up
@@ -1234,8 +1234,6 @@ namespace {
runner.start(&txn);
- unsigned int opID = 100;
- txn.setOpID(opID);
txn.setCheckForInterruptStatus(kInterruptedStatus);
getReplCoord()->interrupt(opID);
diff --git a/src/mongo/db/repl/sync_source_feedback.cpp b/src/mongo/db/repl/sync_source_feedback.cpp
index 6773758ef7c..f11e420612a 100644
--- a/src/mongo/db/repl/sync_source_feedback.cpp
+++ b/src/mongo/db/repl/sync_source_feedback.cpp
@@ -157,7 +157,6 @@ namespace repl {
void SyncSourceFeedback::run() {
Client::initThread("SyncSourceFeedback");
- OperationContextImpl txn;
ReplicationCoordinator* replCoord = getGlobalReplicationCoordinator();
while (true) { // breaks once _shutdownSignaled is true
@@ -174,6 +173,7 @@ namespace repl {
_positionChanged = false;
}
+ auto txn = cc().getServiceContext()->newOpCtx();
MemberState state = replCoord->getMemberState();
if (state.primary() || state.startup()) {
_resetConnection();
@@ -192,14 +192,14 @@ namespace repl {
_positionChanged = true;
continue;
}
- if (!_connect(&txn, target)) {
+ if (!_connect(txn.get(), target)) {
sleepmillis(500);
boost::unique_lock<boost::mutex> lock(_mtx);
_positionChanged = true;
continue;
}
}
- Status status = updateUpstream(&txn);
+ Status status = updateUpstream(txn.get());
if (!status.isOK()) {
sleepmillis(500);
boost::unique_lock<boost::mutex> lock(_mtx);
diff --git a/src/mongo/db/repl/sync_tail.cpp b/src/mongo/db/repl/sync_tail.cpp
index 0e690b80c30..350a737ee72 100644
--- a/src/mongo/db/repl/sync_tail.cpp
+++ b/src/mongo/db/repl/sync_tail.cpp
@@ -136,7 +136,7 @@ namespace repl {
}
// Count each log op application as a separate operation, for reporting purposes
- CurOp::get(txn)->reset();
+ CurOp individualOp(txn);
const char *ns = op.getStringField("ns");
verify(ns);
diff --git a/src/mongo/db/repl/sync_tail_test.cpp b/src/mongo/db/repl/sync_tail_test.cpp
index 9e20ce78818..94d1c073007 100644
--- a/src/mongo/db/repl/sync_tail_test.cpp
+++ b/src/mongo/db/repl/sync_tail_test.cpp
@@ -64,16 +64,6 @@ namespace {
void BackgroundSyncMock::consume() { }
void BackgroundSyncMock::waitForMore() { }
- class OperationContextSyncTailMock : public OperationContextReplMock {
- public:
- Client* getClient() const override;
- };
-
- Client* OperationContextSyncTailMock::getClient() const {
- Client::initThreadIfNotAlready();
- return &cc();
- }
-
class SyncTailTest : public unittest::Test {
public:
SyncTailTest();
@@ -112,7 +102,9 @@ namespace {
replSettings.oplogSize = 5 * 1024 * 1024;
setGlobalReplicationCoordinator(new ReplicationCoordinatorMock(replSettings));
- _txn.reset(new OperationContextSyncTailMock());
+
+ Client::initThreadIfNotAlready();
+ _txn.reset(new OperationContextReplMock(&cc(), 0));
_opsApplied = 0;
_applyOp = [](OperationContext* txn,
Database* db,
diff --git a/src/mongo/db/service_context.h b/src/mongo/db/service_context.h
index 3833ff69d85..675b9dfd1ae 100644
--- a/src/mongo/db/service_context.h
+++ b/src/mongo/db/service_context.h
@@ -251,9 +251,9 @@ namespace mongo {
virtual void registerKillOpListener(KillOpListenerInterface* listener) = 0;
/**
- * Returns a new OperationContext. Caller owns pointer.
+ * Returns a new OperationContext.
*/
- virtual OperationContext* newOpCtx() = 0;
+ virtual std::unique_ptr<OperationContext> newOpCtx() = 0;
//
// Global OpObserver.
diff --git a/src/mongo/db/service_context_d.cpp b/src/mongo/db/service_context_d.cpp
index eb00449c625..a9b22a986fb 100644
--- a/src/mongo/db/service_context_d.cpp
+++ b/src/mongo/db/service_context_d.cpp
@@ -227,14 +227,11 @@ namespace mongo {
if (!opCtx) {
return false;
}
- for( CurOp *k = CurOp::get(opCtx); k; k = k->parent() ) {
- if ( k->opNum() != opId )
- continue;
-
- _killOperation_inlock(opCtx);
- return true;
+ if (opCtx->getOpID() != opId) {
+ return false;
}
- return false;
+ _killOperation_inlock(opCtx);
+ return true;
}
void ServiceContextMongoD::_killOperation_inlock(OperationContext* opCtx) {
@@ -295,8 +292,8 @@ namespace mongo {
_killOpListeners.push_back(listener);
}
- OperationContext* ServiceContextMongoD::newOpCtx() {
- return new OperationContextImpl();
+ std::unique_ptr<OperationContext> ServiceContextMongoD::newOpCtx() {
+ return stdx::make_unique<OperationContextImpl>();
}
void ServiceContextMongoD::setOpObserver(std::unique_ptr<OpObserver> opObserver) {
diff --git a/src/mongo/db/service_context_d.h b/src/mongo/db/service_context_d.h
index 1d707f33d63..14ec7dc475d 100644
--- a/src/mongo/db/service_context_d.h
+++ b/src/mongo/db/service_context_d.h
@@ -72,7 +72,7 @@ namespace mongo {
void registerKillOpListener(KillOpListenerInterface* listener);
- OperationContext* newOpCtx();
+ std::unique_ptr<OperationContext> newOpCtx();
void setOpObserver(std::unique_ptr<OpObserver> opObserver);
diff --git a/src/mongo/db/service_context_noop.cpp b/src/mongo/db/service_context_noop.cpp
index 47c3efe8797..87bff0c7932 100644
--- a/src/mongo/db/service_context_noop.cpp
+++ b/src/mongo/db/service_context_noop.cpp
@@ -32,6 +32,7 @@
#include "mongo/db/operation_context_noop.h"
#include "mongo/db/op_observer.h"
+#include "mongo/stdx/memory.h"
namespace mongo {
@@ -81,8 +82,8 @@ namespace mongo {
void ServiceContextNoop::registerKillOpListener(KillOpListenerInterface* listener) {
}
- OperationContext* ServiceContextNoop::newOpCtx() {
- return new OperationContextNoop();
+ std::unique_ptr<OperationContext> ServiceContextNoop::newOpCtx() {
+ return stdx::make_unique<OperationContextNoop>();
}
void ServiceContextNoop::setOpObserver(std::unique_ptr<OpObserver> opObserver) {
diff --git a/src/mongo/db/service_context_noop.h b/src/mongo/db/service_context_noop.h
index b7f541b784f..833c37f975a 100644
--- a/src/mongo/db/service_context_noop.h
+++ b/src/mongo/db/service_context_noop.h
@@ -57,7 +57,7 @@ namespace mongo {
void registerKillOpListener(KillOpListenerInterface* listener);
- OperationContext* newOpCtx();
+ std::unique_ptr<OperationContext> newOpCtx();
void setOpObserver(std::unique_ptr<OpObserver> opObserver);
diff --git a/src/mongo/db/storage/SConscript b/src/mongo/db/storage/SConscript
index 83d21072778..3b9fc94fb35 100644
--- a/src/mongo/db/storage/SConscript
+++ b/src/mongo/db/storage/SConscript
@@ -35,6 +35,7 @@ env.Library(
],
LIBDEPS=[
'$BUILD_DIR/mongo/db/catalog/collection_options',
+ '$BUILD_DIR/mongo/db/service_context',
],
)
diff --git a/src/mongo/db/storage/mmap_v1/SConscript b/src/mongo/db/storage/mmap_v1/SConscript
index c7cbbd07e2c..841e8f9ce48 100644
--- a/src/mongo/db/storage/mmap_v1/SConscript
+++ b/src/mongo/db/storage/mmap_v1/SConscript
@@ -110,6 +110,7 @@ env.Library(
LIBDEPS= [
'extent',
'$BUILD_DIR/mongo/db/commands/server_status_core',
+ '$BUILD_DIR/mongo/db/service_context',
'$BUILD_DIR/mongo/util/concurrency/spin_lock',
'$BUILD_DIR/mongo/util/progress_meter',
]
@@ -195,7 +196,8 @@ env.Library(
'btree/key.cpp'
],
LIBDEPS= [
- '$BUILD_DIR/mongo/bson/bson'
+ '$BUILD_DIR/mongo/bson/bson',
+ '$BUILD_DIR/mongo/db/service_context',
]
)
diff --git a/src/mongo/db/storage/mmap_v1/data_file_sync.cpp b/src/mongo/db/storage/mmap_v1/data_file_sync.cpp
index d4d2cb43fe3..9579278ded1 100644
--- a/src/mongo/db/storage/mmap_v1/data_file_sync.cpp
+++ b/src/mongo/db/storage/mmap_v1/data_file_sync.cpp
@@ -32,6 +32,7 @@
#include "mongo/db/storage/mmap_v1/data_file_sync.h"
+#include "mongo/db/client.h"
#include "mongo/db/commands/server_status_metric.h"
#include "mongo/db/service_context.h"
#include "mongo/db/instance.h"
diff --git a/src/mongo/dbtests/indexupdatetests.cpp b/src/mongo/dbtests/indexupdatetests.cpp
index a9cda7a01b6..1141009a5ea 100644
--- a/src/mongo/dbtests/indexupdatetests.cpp
+++ b/src/mongo/dbtests/indexupdatetests.cpp
@@ -482,8 +482,6 @@ namespace IndexUpdateTests {
}
wunit.commit();
}
- // Initialize curop.
- CurOp::get(_txn)->reset();
// Request an interrupt.
getGlobalServiceContext()->setKillAllOperations();
BSONObj indexInfo = BSON( "key" << BSON( "a" << 1 ) << "ns" << _ns << "name" << "a_1" );
@@ -515,8 +513,6 @@ namespace IndexUpdateTests {
}
wunit.commit();
}
- // Initialize curop.
- CurOp::get(_txn)->reset();
// Request an interrupt.
getGlobalServiceContext()->setKillAllOperations();
BSONObj indexInfo = BSON( "key" << BSON( "a" << 1 ) << "ns" << _ns << "name" << "a_1" );
@@ -551,8 +547,6 @@ namespace IndexUpdateTests {
}
wunit.commit();
}
- // Initialize curop.
- CurOp::get(_txn)->reset();
// Request an interrupt.
getGlobalServiceContext()->setKillAllOperations();
BSONObj indexInfo = BSON( "key" << BSON( "_id" << 1 ) <<
@@ -589,8 +583,6 @@ namespace IndexUpdateTests {
}
wunit.commit();
}
- // Initialize curop.
- CurOp::get(_txn)->reset();
// Request an interrupt.
getGlobalServiceContext()->setKillAllOperations();
BSONObj indexInfo = BSON( "key" << BSON( "_id" << 1 ) <<
@@ -616,8 +608,6 @@ namespace IndexUpdateTests {
}
// Start with just _id
ASSERT_EQUALS( 1U, _client.getIndexSpecs(_ns).size());
- // Initialize curop.
- CurOp::get(_txn)->reset();
// Request an interrupt.
getGlobalServiceContext()->setKillAllOperations();
// The call is not interrupted.
diff --git a/src/mongo/dbtests/querytests.cpp b/src/mongo/dbtests/querytests.cpp
index 5926472b7e6..d1da41ed617 100644
--- a/src/mongo/dbtests/querytests.cpp
+++ b/src/mongo/dbtests/querytests.cpp
@@ -217,7 +217,6 @@ namespace QueryTests {
public:
ClientBase() : _client(&_txn) {
mongo::LastError::get(_txn.getClient()).reset();
- CurOp::get(_txn)->reset();
}
virtual ~ClientBase() {
mongo::LastError::get(_txn.getClient()).reset();
diff --git a/src/mongo/dbtests/threadedtests.cpp b/src/mongo/dbtests/threadedtests.cpp
index 4470387aeac..b03f5877e17 100644
--- a/src/mongo/dbtests/threadedtests.cpp
+++ b/src/mongo/dbtests/threadedtests.cpp
@@ -38,6 +38,7 @@
#include <iostream>
#include "mongo/config.h"
+#include "mongo/db/client.h"
#include "mongo/db/concurrency/d_concurrency.h"
#include "mongo/db/concurrency/lock_state.h"
#include "mongo/db/operation_context_impl.h"
diff --git a/src/mongo/s/d_migrate.cpp b/src/mongo/s/d_migrate.cpp
index b97b2221676..b3aa9312038 100644
--- a/src/mongo/s/d_migrate.cpp
+++ b/src/mongo/s/d_migrate.cpp
@@ -2639,9 +2639,6 @@ namespace {
AuthorizationSession::get(txn.getClient())->grantInternalAuthorization();
}
- // Make curop active so this will show up in currOp.
- CurOp::get(txn)->reset();
-
migrateStatus.go(&txn, ns, min, max, shardKeyPattern, fromShard, epoch, writeConcern);
}