summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Schwerin <schwerin@mongodb.com>2015-05-22 15:24:52 -0400
committerAndy Schwerin <schwerin@mongodb.com>2015-05-29 10:28:03 -0400
commit4ea38c308da292f43e29d32b1b53b7324db0bafe (patch)
tree22d166a388262ae5837d0c4e44f42748194e3e47
parent5c2d133871b2ad2adf6c617364d036ca25261f2d (diff)
downloadmongo-4ea38c308da292f43e29d32b1b53b7324db0bafe.tar.gz
SERVER-14995 Move operation id, lockState and client fields to OperationContext.
They have been moved from OperationContextImpl. Furthermore, the CurOp stack is now attached to OperationContext, instead of Client. With this change, an operation's lifetime is governed by the lifetime of an OperationContext object. The "_active" field of CurOp is therefore no longer meaingful. This required fixing the lifetime of OperationContext in a few places. A future change will adjust operation lifetime timing to time the lifetime of the OperationContext object, as well.
-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, 222 insertions, 255 deletions
diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript
index da65f0978c2..d1cb5273109 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 91dcffe3a4f..f0fbdad5163 100644
--- a/src/mongo/db/commands/getmore_cmd.cpp
+++ b/src/mongo/db/commands/getmore_cmd.cpp
@@ -37,16 +37,18 @@
#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/commands/cursor_responses.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/repl/oplog.h"
-#include "mongo/db/service_context.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 d7db78aae5c..9759df2e68d 100644
--- a/src/mongo/db/repl/SConscript
+++ b/src/mongo/db/repl/SConscript
@@ -468,6 +468,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 164cb3c99c7..0cfd1834b50 100644
--- a/src/mongo/db/repl/bgsync.cpp
+++ b/src/mongo/db/repl/bgsync.cpp
@@ -184,8 +184,6 @@ namespace {
return;
}
- OperationContextImpl txn;
-
// We need to wait until initial sync has started.
if (_replCoord->getMyLastOptime().isNull()) {
sleepsecs(1);
@@ -193,7 +191,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 fdde13dbc71..0757f671552 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);
@@ -1176,7 +1175,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
@@ -1195,8 +1195,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 f3deb22ff7d..a7fdbbcfc94 100644
--- a/src/mongo/s/d_migrate.cpp
+++ b/src/mongo/s/d_migrate.cpp
@@ -2657,9 +2657,6 @@ namespace mongo {
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);
}