summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db')
-rw-r--r--src/mongo/db/client.cpp1
-rw-r--r--src/mongo/db/client.h1
-rw-r--r--src/mongo/db/commands/find_and_modify.cpp1
-rw-r--r--src/mongo/db/commands/get_last_error.cpp22
-rw-r--r--src/mongo/db/commands/write_commands/batch_executor.cpp10
-rw-r--r--src/mongo/db/commands/write_commands/batch_executor.h5
-rw-r--r--src/mongo/db/commands/write_commands/write_commands.cpp4
-rw-r--r--src/mongo/db/db.cpp5
-rw-r--r--src/mongo/db/dbcommands_generic.cpp2
-rw-r--r--src/mongo/db/dbdirectclient.cpp9
-rw-r--r--src/mongo/db/instance.cpp20
-rw-r--r--src/mongo/db/lasterror.cpp156
-rw-r--r--src/mongo/db/lasterror.h150
-rw-r--r--src/mongo/db/ops/update_result.cpp1
-rw-r--r--src/mongo/db/repl/replication_info.cpp3
-rw-r--r--src/mongo/db/repl/replset_commands.cpp3
16 files changed, 158 insertions, 235 deletions
diff --git a/src/mongo/db/client.cpp b/src/mongo/db/client.cpp
index cc4a7c69cab..a2e510f4bb0 100644
--- a/src/mongo/db/client.cpp
+++ b/src/mongo/db/client.cpp
@@ -83,7 +83,6 @@ namespace mongo {
}
setThreadName(fullDesc.c_str());
- mongo::lastError.initThread();
// Create the client obj, attach to thread
*currentClient.get() = service->makeClient(fullDesc, mp);
diff --git a/src/mongo/db/client.h b/src/mongo/db/client.h
index f81bc91bf37..63750b69523 100644
--- a/src/mongo/db/client.h
+++ b/src/mongo/db/client.h
@@ -40,7 +40,6 @@
#include <boost/thread/thread.hpp>
#include "mongo/db/client_basic.h"
-#include "mongo/db/lasterror.h"
#include "mongo/db/namespace_string.h"
#include "mongo/db/operation_context.h"
#include "mongo/db/service_context.h"
diff --git a/src/mongo/db/commands/find_and_modify.cpp b/src/mongo/db/commands/find_and_modify.cpp
index b8e76b8e0a2..7dcdab369a2 100644
--- a/src/mongo/db/commands/find_and_modify.cpp
+++ b/src/mongo/db/commands/find_and_modify.cpp
@@ -43,6 +43,7 @@
#include "mongo/db/concurrency/write_conflict_exception.h"
#include "mongo/db/db_raii.h"
#include "mongo/db/exec/working_set_common.h"
+#include "mongo/db/lasterror.h"
#include "mongo/db/namespace_string.h"
#include "mongo/db/operation_context.h"
#include "mongo/db/ops/delete_request.h"
diff --git a/src/mongo/db/commands/get_last_error.cpp b/src/mongo/db/commands/get_last_error.cpp
index b3a6ffe84ec..54a9fb469d5 100644
--- a/src/mongo/db/commands/get_last_error.cpp
+++ b/src/mongo/db/commands/get_last_error.cpp
@@ -72,9 +72,7 @@ namespace mongo {
int,
string& errmsg,
BSONObjBuilder& result) {
- LastError *le = lastError.get();
- verify( le );
- le->reset();
+ LastError::get(txn->getClient()).reset();
return true;
}
} cmdResetError;
@@ -88,7 +86,7 @@ namespace mongo {
const BSONObj& cmdObj,
std::vector<Privilege>* out) {} // No auth required
virtual void help( stringstream& help ) const {
- lastError.disableForCommand(); // SERVER-11492
+ LastError::get(cc()).disable(); // SERVER-11492
help << "return error status of the last operation on this connection\n"
<< "options:\n"
<< " { fsync:true } - fsync before returning, or wait for journal commit if running with --journal\n"
@@ -128,7 +126,8 @@ namespace mongo {
// err is null.
//
- LastError *le = lastError.disableForCommand();
+ LastError *le = &LastError::get(txn->getClient());
+ le->disable();
// Always append lastOp and connectionId
Client& c = *txn->getClient();
@@ -173,7 +172,7 @@ namespace mongo {
// Errors aren't reported when wOpTime is used
if ( !lastOpTimePresent ) {
- if ( le->nPrev != 1 ) {
+ if ( le->getNPrev() != 1 ) {
errorOccurred = LastError::noError.appendSelf( result, false );
}
else {
@@ -284,12 +283,13 @@ namespace mongo {
int,
string& errmsg,
BSONObjBuilder& result) {
- LastError *le = lastError.disableForCommand();
- le->appendSelf( result );
- if ( le->valid )
- result.append( "nPrev", le->nPrev );
+ LastError *le = &LastError::get(txn->getClient());
+ le->disable();
+ le->appendSelf(result, true);
+ if (le->isValid())
+ result.append("nPrev", le->getNPrev());
else
- result.append( "nPrev", -1 );
+ result.append("nPrev", -1);
return true;
}
} cmdGetPrevError;
diff --git a/src/mongo/db/commands/write_commands/batch_executor.cpp b/src/mongo/db/commands/write_commands/batch_executor.cpp
index 72bdb1fc144..ae57fdbecbb 100644
--- a/src/mongo/db/commands/write_commands/batch_executor.cpp
+++ b/src/mongo/db/commands/write_commands/batch_executor.cpp
@@ -550,8 +550,10 @@ namespace mongo {
if ( currWrite.getOpType() == BatchedCommandRequest::BatchType_Insert ) {
_stats->numInserted += stats.n;
- _le->nObjects = stats.n;
currentOp->debug().ninserted += stats.n;
+ if (!error) {
+ _le->recordInsert(stats.n);
+ }
}
else if ( currWrite.getOpType() == BatchedCommandRequest::BatchType_Update ) {
if ( stats.upsertedID.isEmpty() ) {
@@ -562,7 +564,7 @@ namespace mongo {
++_stats->numUpserted;
}
- if ( !error ) {
+ if (!error) {
_le->recordUpdate( stats.upsertedID.isEmpty() && stats.n > 0,
stats.n,
stats.upsertedID );
@@ -577,8 +579,8 @@ namespace mongo {
currentOp->debug().ndeleted += stats.n;
}
- if (error && !_le->disabled) {
- _le->raiseError(error->getErrCode(), error->getErrMessage().c_str());
+ if (error) {
+ _le->setLastError(error->getErrCode(), error->getErrMessage().c_str());
}
}
diff --git a/src/mongo/db/commands/write_commands/batch_executor.h b/src/mongo/db/commands/write_commands/batch_executor.h
index 613fb281777..e5d55a5b9fb 100644
--- a/src/mongo/db/commands/write_commands/batch_executor.h
+++ b/src/mongo/db/commands/write_commands/batch_executor.h
@@ -44,12 +44,11 @@ namespace mongo {
class BSONObjBuilder;
class CurOp;
+ class LastError;
class OpCounters;
class OperationContext;
- struct LastError;
-
- struct WriteOpStats;
class WriteBatchStats;
+ struct WriteOpStats;
/**
* An instance of WriteBatchExecutor is an object capable of issuing a write batch.
diff --git a/src/mongo/db/commands/write_commands/write_commands.cpp b/src/mongo/db/commands/write_commands/write_commands.cpp
index d6d6d7ff137..a1d217d7525 100644
--- a/src/mongo/db/commands/write_commands/write_commands.cpp
+++ b/src/mongo/db/commands/write_commands/write_commands.cpp
@@ -104,7 +104,7 @@ namespace mongo {
// TODO: Remove this when we standardize GLE reporting from commands
if ( !status.isOK() ) {
- setLastError( status.code(), status.reason().c_str() );
+ LastError::get(client).setLastError(status.code(), status.reason());
}
return status;
@@ -145,7 +145,7 @@ namespace mongo {
WriteBatchExecutor writeBatchExecutor(txn,
&globalOpCounters,
- lastError.get());
+ &LastError::get(txn->getClient()));
writeBatchExecutor.executeBatch( request, &response );
diff --git a/src/mongo/db/db.cpp b/src/mongo/db/db.cpp
index 92bb4177c91..aed1bf00958 100644
--- a/src/mongo/db/db.cpp
+++ b/src/mongo/db/db.cpp
@@ -70,7 +70,6 @@
#include "mongo/db/instance.h"
#include "mongo/db/introspect.h"
#include "mongo/db/json.h"
-#include "mongo/db/lasterror.h"
#include "mongo/db/log_process_details.h"
#include "mongo/db/mongod_options.h"
#include "mongo/db/op_observer.h"
@@ -157,7 +156,7 @@ namespace mongo {
Client::initThread("conn", p);
}
- virtual void process( Message& m , AbstractMessagingPort* port , LastError * le) {
+ virtual void process(Message& m , AbstractMessagingPort* port) {
OperationContextImpl txn;
while ( true ) {
if ( inShutdown() ) {
@@ -165,8 +164,6 @@ namespace mongo {
break;
}
- lastError.startRequest( m , le );
-
DbResponse dbresponse;
assembleResponse(&txn, m, dbresponse, port->remote());
diff --git a/src/mongo/db/dbcommands_generic.cpp b/src/mongo/db/dbcommands_generic.cpp
index c07dc30a1dc..b9a3c7ef6af 100644
--- a/src/mongo/db/dbcommands_generic.cpp
+++ b/src/mongo/db/dbcommands_generic.cpp
@@ -330,7 +330,7 @@ namespace mongo {
int,
string& errmsg,
BSONObjBuilder& result) {
- setLastError(10038, "forced error");
+ LastError::get(txn->getClient()).setLastError(10038, "forced error");
return false;
}
} cmdForceError;
diff --git a/src/mongo/db/dbdirectclient.cpp b/src/mongo/db/dbdirectclient.cpp
index 41b75377060..3aee1750172 100644
--- a/src/mongo/db/dbdirectclient.cpp
+++ b/src/mongo/db/dbdirectclient.cpp
@@ -33,6 +33,7 @@
#include "mongo/db/client.h"
#include "mongo/db/commands.h"
#include "mongo/db/instance.h"
+#include "mongo/db/lasterror.h"
#include "mongo/db/operation_context.h"
#include "mongo/util/log.h"
@@ -122,9 +123,7 @@ namespace mongo {
bool assertOk,
string* actualServer) {
DirectClientScope directClientScope(_txn);
- if (lastError._get()) {
- lastError.startRequest(toSend, lastError._get());
- }
+ LastError::get(_txn->getClient()).startRequest();
DbResponse dbResponse;
assembleResponse(_txn, toSend, dbResponse, dummyHost);
@@ -139,9 +138,7 @@ namespace mongo {
void DBDirectClient::say(Message& toSend, bool isRetry, string* actualServer) {
DirectClientScope directClientScope(_txn);
- if (lastError._get()) {
- lastError.startRequest(toSend, lastError._get());
- }
+ LastError::get(_txn->getClient()).startRequest();
DbResponse dbResponse;
assembleResponse(_txn, toSend, dbResponse, dummyHost);
diff --git a/src/mongo/db/instance.cpp b/src/mongo/db/instance.cpp
index 80bf95116ce..099492d607a 100644
--- a/src/mongo/db/instance.cpp
+++ b/src/mongo/db/instance.cpp
@@ -389,6 +389,7 @@ namespace {
Client& c = *txn->getClient();
if (!c.isInDirectClient()) {
+ LastError::get(c).startRequest();
AuthorizationSession::get(c)->startRequest(txn);
// We should not be holding any locks at this point
@@ -556,14 +557,14 @@ namespace {
}
}
catch (const UserException& ue) {
- setLastError(ue.getCode(), ue.getInfo().msg.c_str());
+ LastError::get(c).setLastError(ue.getCode(), ue.getInfo().msg);
MONGO_LOG_COMPONENT(3, responseComponent)
<< " Caught Assertion in " << opToString(op) << ", continuing "
<< ue.toString() << endl;
debug.exceptionInfo = ue.getInfo();
}
catch (const AssertionException& e) {
- setLastError(e.getCode(), e.getInfo().msg.c_str());
+ LastError::get(c).setLastError(e.getCode(), e.getInfo().msg);
MONGO_LOG_COMPONENT(3, responseComponent)
<< " Caught Assertion in " << opToString(op) << ", continuing "
<< e.toString() << endl;
@@ -604,6 +605,7 @@ namespace {
}
void receivedKillCursors(OperationContext* txn, Message& m) {
+ LastError::get(txn->getClient()).disable();
DbMessage dbmessage(m);
int n = dbmessage.pullInt();
@@ -700,7 +702,8 @@ namespace {
UpdateResult res = UpdateStage::makeUpdateResult(exec.get(), &op.debug());
// for getlasterror
- lastError.getSafe()->recordUpdate( res.existing , res.numMatched , res.upserted );
+ LastError::get(txn->getClient()).recordUpdate(
+ res.existing, res.numMatched, res.upserted);
return;
}
break;
@@ -753,7 +756,8 @@ namespace {
uassertStatusOK(exec->executePlan());
UpdateResult res = UpdateStage::makeUpdateResult(exec.get(), &op.debug());
- lastError.getSafe()->recordUpdate( res.existing , res.numMatched , res.upserted );
+ LastError::get(txn->getClient()).recordUpdate(
+ res.existing, res.numMatched, res.upserted);
} MONGO_WRITE_CONFLICT_RETRY_LOOP_END(txn, "update", nsString.ns());
}
@@ -811,7 +815,7 @@ namespace {
// Run the plan and get the number of docs deleted.
uassertStatusOK(exec->executePlan());
long long n = DeleteStage::getNumDeleted(exec.get());
- lastError.getSafe()->recordDelete(n);
+ LastError::get(txn->getClient()).recordDelete(n);
op.debug().ndeleted = n;
break;
@@ -1001,7 +1005,7 @@ namespace {
globalOpCounters.incInsertInWriteLock(i);
throw;
}
- setLastError(ex.getCode(), ex.getInfo().msg.c_str());
+ LastError::get(txn->getClient()).setLastError(ex.getCode(), ex.getInfo().msg);
// otherwise ignore and keep going
}
}
@@ -1055,7 +1059,7 @@ namespace {
convertSystemIndexInsertsToCommands(d, &allCmdsBuilder);
}
catch (const DBException& ex) {
- setLastError(ex.getCode(), ex.getInfo().msg.c_str());
+ LastError::get(txn->getClient()).setLastError(ex.getCode(), ex.getInfo().msg);
curOp.debug().exceptionInfo = ex.getInfo();
return;
}
@@ -1077,7 +1081,7 @@ namespace {
uassertStatusOK(Command::getStatusFromCommandResult(resultBuilder.done()));
}
catch (const DBException& ex) {
- setLastError(ex.getCode(), ex.getInfo().msg.c_str());
+ LastError::get(txn->getClient()).setLastError(ex.getCode(), ex.getInfo().msg);
curOp.debug().exceptionInfo = ex.getInfo();
if (!keepGoing) {
return;
diff --git a/src/mongo/db/lasterror.cpp b/src/mongo/db/lasterror.cpp
index d0a22d56b51..d242cdedc1a 100644
--- a/src/mongo/db/lasterror.cpp
+++ b/src/mongo/db/lasterror.cpp
@@ -27,139 +27,91 @@
* then also delete it in the license file.
*/
-#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kDefault
-
#include "mongo/platform/basic.h"
#include "mongo/db/lasterror.h"
#include "mongo/db/jsobj.h"
-#include "mongo/util/debug_util.h"
-#include "mongo/util/log.h"
-#include "mongo/util/net/message.h"
+#include "mongo/util/assert_util.h"
namespace mongo {
- using std::endl;
-
LastError LastError::noError;
- LastErrorHolder lastError;
-
- bool isShell = false;
- void setLastError(int code , const char *msg) {
- LastError *le = lastError.get();
- if ( le == 0 ) {
- /* might be intentional (non-user thread) */
- DEV {
- static unsigned n;
- if( ++n < 4 && !isShell ) log() << "dev: lastError==0 won't report:" << msg << endl;
- }
- }
- else if ( le->disabled ) {
- log() << "lastError disabled, can't report: " << code << ":" << msg << endl;
- }
- else {
- le->raiseError(code, msg);
- }
- }
- bool LastError::appendSelf( BSONObjBuilder &b , bool blankErr ) {
+ const Client::Decoration<LastError> LastError::get = Client::declareDecoration<LastError>();
- if ( !valid ) {
- if ( blankErr )
- b.appendNull( "err" );
- b.append( "n", 0 );
- return false;
- }
-
- if ( msg.empty() ) {
- if ( blankErr ) {
- b.appendNull( "err" );
- }
- }
- else {
- b.append( "err", msg );
- }
+ void LastError::reset(bool valid) {
+ *this = LastError();
+ _valid = valid;
+ }
- if ( code )
- b.append( "code" , code );
- if ( updatedExisting != NotUpdate )
- b.appendBool( "updatedExisting", updatedExisting == True );
- if ( !upsertedId.isEmpty() ) {
- b.append( upsertedId[kUpsertedFieldName] );
+ void LastError::setLastError(int code, std::string msg) {
+ if (_disabled) {
+ return;
}
- b.appendNumber( "n", nObjects );
-
- return ! msg.empty();
+ reset(true);
+ _code = code;
+ _msg = std::move(msg);
}
- LastErrorHolder::~LastErrorHolder() {
+ void LastError::recordInsert(long long nObjects) {
+ reset(true);
+ _nObjects = nObjects;
}
-
- LastError * LastErrorHolder::disableForCommand() {
- LastError *le = _get();
- uassert(13649, "no operation yet", le);
- le->disabled = true;
- le->nPrev--; // caller is a command that shouldn't count as an operation
- return le;
+ void LastError::recordUpdate(bool updateObjects, long long nObjects, BSONObj upsertedId) {
+ reset(true);
+ _nObjects = nObjects;
+ _updatedExisting = updateObjects ? True : False;
+ if ( upsertedId.valid() && upsertedId.hasField(kUpsertedFieldName) )
+ _upsertedId = upsertedId;
}
- LastError * LastErrorHolder::get( bool create ) {
- LastError *ret = _get( create );
- if ( ret && !ret->disabled )
- return ret;
- return 0;
+ void LastError::recordDelete(long long nDeleted) {
+ reset(true);
+ _nObjects = nDeleted;
}
- LastError * LastErrorHolder::getSafe() {
- LastError * le = get(false);
- if ( ! le ) {
- error() << " no LastError!" << std::endl;
- verify( le );
+ bool LastError::appendSelf(BSONObjBuilder &b , bool blankErr) const {
+
+ if (!_valid) {
+ if (blankErr)
+ b.appendNull( "err" );
+ b.append( "n", 0 );
+ return false;
}
- return le;
- }
- LastError * LastErrorHolder::_get( bool create ) {
- LastError * le = _tl.get();
- if ( ! le && create ) {
- le = new LastError();
- _tl.reset( le );
+ if (_msg.empty()) {
+ if (blankErr) {
+ b.appendNull( "err" );
+ }
+ }
+ else {
+ b.append("err", _msg);
}
- return le;
- }
- void LastErrorHolder::release() {
- _tl.release();
- }
+ if (_code)
+ b.append("code" , _code);
+ if (_updatedExisting != NotUpdate)
+ b.appendBool("updatedExisting", _updatedExisting == True);
+ if (!_upsertedId.isEmpty()) {
+ b.append(_upsertedId[kUpsertedFieldName]);
+ }
+ b.appendNumber("n", _nObjects);
- /** ok to call more than once. */
- void LastErrorHolder::initThread() {
- if( ! _tl.get() )
- _tl.reset( new LastError() );
+ return !_msg.empty();
}
- void LastErrorHolder::reset( LastError * le ) {
- _tl.reset( le );
- }
- void prepareErrForNewRequest( Message &m, LastError * err ) {
- // a killCursors message shouldn't affect last error
- verify( err );
- if ( m.operation() == dbKillCursors ) {
- err->disabled = true;
- }
- else {
- err->disabled = false;
- err->nPrev++;
- }
+ void LastError::disable() {
+ invariant(!_disabled);
+ _disabled = true;
+ _nPrev--; // caller is a command that shouldn't count as an operation
}
- LastError * LastErrorHolder::startRequest( Message& m , LastError * le ) {
- verify( le );
- prepareErrForNewRequest( m, le );
- return le;
+ void LastError::startRequest() {
+ _disabled = false;
+ ++_nPrev;
}
} // namespace mongo
diff --git a/src/mongo/db/lasterror.h b/src/mongo/db/lasterror.h
index 5b04b69a57a..55a04c8334d 100644
--- a/src/mongo/db/lasterror.h
+++ b/src/mongo/db/lasterror.h
@@ -29,16 +29,13 @@
#pragma once
-#include <boost/noncopyable.hpp>
-#include <boost/thread/tss.hpp>
#include <string>
+#include "mongo/db/client.h"
#include "mongo/db/jsobj.h"
-#include "mongo/bson/oid.h"
namespace mongo {
class BSONObjBuilder;
- class Message;
static const char kUpsertedFieldName[] = "upserted";
static const char kGLEStatsFieldName[] = "$gleStats";
@@ -46,107 +43,80 @@ namespace mongo {
static const char kGLEStatsLastOpTimeTermFieldName[] = "lastOpTimeTerm";
static const char kGLEStatsElectionIdFieldName[] = "electionId";
- struct LastError {
- int code;
- std::string msg;
- enum UpdatedExistingType { NotUpdate, True, False } updatedExisting;
- // _id field value from inserted doc, returned as kUpsertedFieldName (above)
- BSONObj upsertedId;
- long long nObjects;
- int nPrev;
- bool valid;
- bool disabled;
- void raiseError(int _code , const char *_msg) {
- reset( true );
- code = _code;
- msg = _msg;
- }
- void recordUpdate( bool _updateObjects , long long _nObjects , BSONObj _upsertedId ) {
- reset( true );
- nObjects = _nObjects;
- updatedExisting = _updateObjects ? True : False;
- if ( _upsertedId.valid() && _upsertedId.hasField(kUpsertedFieldName) )
- upsertedId = _upsertedId;
-
- }
- void recordDelete( long long nDeleted ) {
- reset( true );
- nObjects = nDeleted;
- }
- LastError() {
- reset();
- }
- void reset( bool _valid = false ) {
- code = 0;
- msg.clear();
- updatedExisting = NotUpdate;
- nObjects = 0;
- nPrev = 1;
- valid = _valid;
- disabled = false;
- upsertedId = BSONObj();
- }
+ class LastError {
+ public:
+ static const Client::Decoration<LastError> get;
/**
- * @return if there is an err
+ * Resets the object to a newly constructed state. If "valid" is true, marks the last-error
+ * object as "valid".
*/
- bool appendSelf( BSONObjBuilder &b , bool blankErr = true );
-
- struct Disabled : boost::noncopyable {
- Disabled( LastError * le ) {
- _le = le;
- if ( _le ) {
- _prev = _le->disabled;
- _le->disabled = true;
- }
- else {
- _prev = false;
- }
- }
+ void reset(bool valid = false);
- ~Disabled() {
- if ( _le )
- _le->disabled = _prev;
- }
+ /**
+ * when db receives a message/request, call this
+ */
+ void startRequest();
- LastError * _le;
- bool _prev;
- };
+ /**
+ * Disables error recording for the current operation.
+ */
+ void disable();
- static LastError noError;
- };
+ /**
+ * Sets the error information for the current operation, if error recording was not
+ * explicitly disabled via a call to disable() since the call to startRequest.
+ */
+ void setLastError(int code, std::string msg);
- extern class LastErrorHolder {
- public:
- LastErrorHolder(){}
- ~LastErrorHolder();
+ void recordInsert(long long nObjects);
- LastError * get( bool create = false );
- LastError * getSafe();
- LastError * _get( bool create = false ); // may return a disabled LastError
+ void recordUpdate(bool updateObjects, long long nObjects, BSONObj upsertedId);
- void reset( LastError * le );
+ void recordDelete(long long nDeleted);
- /** ok to call more than once. */
- void initThread();
+ /**
+ * Writes the last-error state described by this object to "b".
+ *
+ * If "blankErr" is true, the "err" field will be explicitly set to null in the result
+ * instead of being omitted when the error string is empty.
+ *
+ * Returns true if there is a non-empty error message.
+ */
+ bool appendSelf(BSONObjBuilder &b, bool blankErr) const;
- void release();
+ bool isValid() const { return _valid; }
+ int const getNPrev() const { return _nPrev; }
- /** when db receives a message/request, call this */
- LastError * startRequest( Message& m , LastError * connectionOwned );
+ class Disabled {
+ public:
+ explicit Disabled(LastError* le) : _le(le), _prev(le->_disabled) {
+ _le->_disabled = true;
+ }
- // used to disable lastError reporting while processing a killCursors message
- // disable causes get() to return 0.
- LastError *disableForCommand(); // only call once per command invocation!
- private:
- boost::thread_specific_ptr<LastError> _tl;
+ ~Disabled() {
+ _le->_disabled = _prev;
+ }
- struct Status {
- time_t time;
- LastError *lerr;
+ private:
+ LastError * const _le;
+ const bool _prev;
};
- } lastError;
- void setLastError(int code , const char *msg);
+ static LastError noError;
+
+ private:
+ enum UpdatedExistingType { NotUpdate, True, False };
+
+ int _code = 0;
+ std::string _msg = {};
+ UpdatedExistingType _updatedExisting = NotUpdate;
+ // _id field value from inserted doc, returned as kUpsertedFieldName (above)
+ BSONObj _upsertedId = {};
+ long long _nObjects = 0;
+ int _nPrev = 1;
+ bool _valid = false;
+ bool _disabled = false;
+ };
} // namespace mongo
diff --git a/src/mongo/db/ops/update_result.cpp b/src/mongo/db/ops/update_result.cpp
index f5e31c1a3d8..64b33243131 100644
--- a/src/mongo/db/ops/update_result.cpp
+++ b/src/mongo/db/ops/update_result.cpp
@@ -34,6 +34,7 @@
#include "mongo/db/ops/update_result.h"
+#include "mongo/db/lasterror.h"
#include "mongo/util/log.h"
namespace mongo {
diff --git a/src/mongo/db/repl/replication_info.cpp b/src/mongo/db/repl/replication_info.cpp
index f4cd02426a2..a5303072fbd 100644
--- a/src/mongo/db/repl/replication_info.cpp
+++ b/src/mongo/db/repl/replication_info.cpp
@@ -37,6 +37,7 @@
#include "mongo/db/db_raii.h"
#include "mongo/db/dbhelpers.h"
#include "mongo/db/jsobj.h"
+#include "mongo/db/lasterror.h"
#include "mongo/db/operation_context_impl.h"
#include "mongo/db/query/internal_plans.h"
#include "mongo/db/repl/is_master_response.h"
@@ -216,7 +217,7 @@ namespace repl {
authenticated.
*/
if ( cmdObj["forShell"].trueValue() )
- lastError.disableForCommand();
+ LastError::get(txn->getClient()).disable();
appendReplicationInfo(txn, result, 0);
diff --git a/src/mongo/db/repl/replset_commands.cpp b/src/mongo/db/repl/replset_commands.cpp
index d160351c6b0..e4cc257dcb4 100644
--- a/src/mongo/db/repl/replset_commands.cpp
+++ b/src/mongo/db/repl/replset_commands.cpp
@@ -41,6 +41,7 @@
#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/commands.h"
#include "mongo/db/dbhelpers.h"
+#include "mongo/db/lasterror.h"
#include "mongo/db/service_context.h"
#include "mongo/db/op_observer.h"
#include "mongo/db/repl/initial_sync.h"
@@ -150,7 +151,7 @@ namespace repl {
string& errmsg,
BSONObjBuilder& result) {
if ( cmdObj["forShell"].trueValue() )
- lastError.disableForCommand();
+ LastError::get(txn->getClient()).disable();
Status status = getGlobalReplicationCoordinator()->checkReplEnabledForCommand(&result);
if (!status.isOK())