summaryrefslogtreecommitdiff
path: root/src/mongo/scripting/engine_v8.cpp
diff options
context:
space:
mode:
authorSpencer T Brody <spencer@mongodb.com>2014-11-21 14:37:09 -0500
committerSpencer T Brody <spencer@mongodb.com>2014-12-01 16:31:10 -0500
commit06928da7d219ac9085d666274af4a82d81e99d4c (patch)
treed7fe946b2c80e79c831cd573864f12a9b53328a3 /src/mongo/scripting/engine_v8.cpp
parent080fb4ec9e610402aeee0db4d37cf291812a3c58 (diff)
downloadmongo-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.cpp38
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) {