diff options
author | Spencer T Brody <spencer@mongodb.com> | 2014-11-21 14:37:09 -0500 |
---|---|---|
committer | Spencer T Brody <spencer@mongodb.com> | 2014-12-01 16:31:10 -0500 |
commit | 06928da7d219ac9085d666274af4a82d81e99d4c (patch) | |
tree | d7fe946b2c80e79c831cd573864f12a9b53328a3 /src/mongo/scripting/engine_v8.cpp | |
parent | 080fb4ec9e610402aeee0db4d37cf291812a3c58 (diff) | |
download | mongo-06928da7d219ac9085d666274af4a82d81e99d4c.tar.gz |
SERVER-14143 Re-enable javascript interruption.
This restores the behavior from 2.6 to interrupt server-side javascript contexts, but doesn't fix
the existing bugs with it due to multiple javascript scopes being associated with a single opId and
opIds changing between getMore calls.
Diffstat (limited to 'src/mongo/scripting/engine_v8.cpp')
-rw-r--r-- | src/mongo/scripting/engine_v8.cpp | 38 |
1 files changed, 18 insertions, 20 deletions
diff --git a/src/mongo/scripting/engine_v8.cpp b/src/mongo/scripting/engine_v8.cpp index b4da62fbe21..589085628ab 100644 --- a/src/mongo/scripting/engine_v8.cpp +++ b/src/mongo/scripting/engine_v8.cpp @@ -35,6 +35,7 @@ #include "mongo/base/init.h" #include "mongo/db/global_environment_experiment.h" +#include "mongo/db/operation_context.h" #include "mongo/platform/unordered_set.h" #include "mongo/scripting/v8_db.h" #include "mongo/scripting/v8_utils.h" @@ -385,27 +386,27 @@ namespace mongo { } } - void V8Scope::registerOpId() { + void V8Scope::registerOperation(OperationContext* txn) { scoped_lock giLock(_engine->_globalInterruptLock); - if (_engine->haveGetCurrentOpIdCallback()) { - // this scope has an associated operation - _opId = _engine->getCurrentOpId(); - _engine->_opToScopeMap[_opId] = this; + invariant(_opId == 0); + _opId = txn->getOpID(); + _engine->_opToScopeMap[_opId] = this; + LOG(2) << "V8Scope " << static_cast<const void*>(this) << " registered for op " << _opId; + Status status = txn->checkForInterruptNoAssert(); + if (!status.isOK()) { + kill(); } - else - // no associated op id (e.g. running from shell) - _opId = 0; - LOG(2) << "V8Scope " << static_cast<const void*>(this) << " registered for op " << _opId << endl; } - void V8Scope::unregisterOpId() { + void V8Scope::unregisterOperation() { scoped_lock giLock(_engine->_globalInterruptLock); LOG(2) << "V8Scope " << static_cast<const void*>(this) << " unregistered for op " << _opId << endl; - if (_engine->haveGetCurrentOpIdCallback() || _opId != 0) { + if (_opId != 0) { // scope is currently associated with an operation id V8ScriptEngine::OpIdToScopeMap::iterator it = _engine->_opToScopeMap.find(_opId); if (it != _engine->_opToScopeMap.end()) _engine->_opToScopeMap.erase(it); + _opId = 0; } } @@ -416,7 +417,7 @@ namespace mongo { LOG(2) << "v8 execution interrupted. isolate: " << static_cast<const void*>(_isolate) << endl; return false; } - if (_pendingKill || globalScriptEngine->interrupted()) { + if (isKillPending()) { // kill flag was set before entering our callback LOG(2) << "marked for death while leaving callback. isolate: " << static_cast<const void*>(_isolate) << endl; v8::V8::TerminateExecution(_isolate); @@ -434,7 +435,7 @@ namespace mongo { LOG(2) << "v8 execution interrupted. isolate: " << static_cast<const void*>(_isolate) << endl; return false; } - if (_pendingKill || globalScriptEngine->interrupted()) { + if (isKillPending()) { LOG(2) << "marked for death while leaving callback. isolate: " << static_cast<const void*>(_isolate) << endl; v8::V8::TerminateExecution(_isolate); return false; @@ -456,7 +457,7 @@ namespace mongo { /** check if there is a pending killOp request */ bool V8Scope::isKillPending() const { - return _pendingKill || _engine->interrupted(); + return _pendingKill; } OperationContext* V8Scope::getOpContext() const { @@ -486,6 +487,7 @@ namespace mongo { _interruptLock("ScopeInterruptLock"), _inNativeExecution(true), _pendingKill(false), + _opId(0), _opCtx(NULL) { // create new isolate and enter it via a scope @@ -559,13 +561,10 @@ namespace mongo { // install global utility functions installGlobalUtils(*this); - - // Don't add anything that can throw after this line otherwise we won't be unregistered. - registerOpId(); } V8Scope::~V8Scope() { - unregisterOpId(); + unregisterOperation(); } bool V8Scope::hasOutOfMemoryException() { @@ -1323,11 +1322,10 @@ namespace mongo { void V8Scope::reset() { V8_SIMPLE_HEADER - unregisterOpId(); + unregisterOperation(); _error = ""; _pendingKill = false; _inNativeExecution = true; - registerOpId(); } v8::Local<v8::Value> V8Scope::newFunction(const StringData& code) { |