summaryrefslogtreecommitdiff
path: root/src/mongo/scripting
diff options
context:
space:
mode:
authorJason Carey <jcarey@argv.me>2015-07-24 15:43:01 -0400
committerJason Carey <jcarey@argv.me>2015-07-28 18:30:39 -0400
commit99103f65251459ea2fc8ad7e096284799702a234 (patch)
tree3098fabce8b8c871b0baf3e35c5d0c3add23e06a /src/mongo/scripting
parent4bc0ca5f2190f851c25bd09f33bedbe57b23f758 (diff)
downloadmongo-99103f65251459ea2fc8ad7e096284799702a234.tar.gz
SERVER-19641 cleanup the js scope in quit()
make leak sanitizer happy
Diffstat (limited to 'src/mongo/scripting')
-rw-r--r--src/mongo/scripting/mozjs/exception.cpp19
-rw-r--r--src/mongo/scripting/mozjs/implscope.cpp17
-rw-r--r--src/mongo/scripting/mozjs/implscope.h5
-rw-r--r--src/mongo/scripting/mozjs/mongo.cpp12
-rw-r--r--src/mongo/scripting/mozjs/mongo.h3
-rw-r--r--src/mongo/scripting/mozjs/proxyscope.cpp7
6 files changed, 56 insertions, 7 deletions
diff --git a/src/mongo/scripting/mozjs/exception.cpp b/src/mongo/scripting/mozjs/exception.cpp
index bae718c0b92..1d6880da05f 100644
--- a/src/mongo/scripting/mozjs/exception.cpp
+++ b/src/mongo/scripting/mozjs/exception.cpp
@@ -40,9 +40,14 @@ namespace mozjs {
namespace {
-JSErrorFormatString kFormatString = {"{0}", 1, JSEXN_ERR};
+JSErrorFormatString kErrorFormatString = {"{0}", 1, JSEXN_ERR};
const JSErrorFormatString* errorCallback(void* data, const unsigned code) {
- return &kFormatString;
+ return &kErrorFormatString;
+}
+
+JSErrorFormatString kUncatchableErrorFormatString = {"{0}", 1, JSEXN_NONE};
+const JSErrorFormatString* uncatchableErrorCallback(void* data, const unsigned code) {
+ return &kUncatchableErrorFormatString;
}
} // namespace
@@ -50,11 +55,17 @@ const JSErrorFormatString* errorCallback(void* data, const unsigned code) {
void mongoToJSException(JSContext* cx) {
auto status = exceptionToStatus();
- JS_ReportErrorNumber(cx, errorCallback, nullptr, status.code(), status.reason().c_str());
+ auto callback =
+ status.code() == ErrorCodes::JSUncatchableError ? uncatchableErrorCallback : errorCallback;
+
+ JS_ReportErrorNumber(cx, callback, nullptr, status.code(), status.reason().c_str());
}
void setJSException(JSContext* cx, ErrorCodes::Error code, StringData sd) {
- JS_ReportErrorNumber(cx, errorCallback, nullptr, code, sd.rawData());
+ auto callback =
+ code == ErrorCodes::JSUncatchableError ? uncatchableErrorCallback : errorCallback;
+
+ JS_ReportErrorNumber(cx, callback, nullptr, code, sd.rawData());
}
Status currentJSExceptionToStatus(JSContext* cx, ErrorCodes::Error altCode, StringData altReason) {
diff --git a/src/mongo/scripting/mozjs/implscope.cpp b/src/mongo/scripting/mozjs/implscope.cpp
index f7574aa48f2..e71fc973949 100644
--- a/src/mongo/scripting/mozjs/implscope.cpp
+++ b/src/mongo/scripting/mozjs/implscope.cpp
@@ -227,6 +227,7 @@ MozJSImplScope::MozJSImplScope(MozJSScriptEngine* engine)
_pendingGC(false),
_connectState(ConnectState::Not),
_status(Status::OK()),
+ _quickExit(false),
_binDataProto(_context),
_bsonProto(_context),
_countDownLatchProto(_context),
@@ -707,6 +708,9 @@ bool MozJSImplScope::_checkErrorState(bool success, bool reportError, bool asser
if (success)
return false;
+ if (_quickExit)
+ return false;
+
if (_status.isOK()) {
_status = Status(ErrorCodes::UnknownError, "Unknown Failure from JSInterpreter");
}
@@ -736,6 +740,19 @@ MozJSImplScope* MozJSImplScope::getThreadScope() {
return kCurrentScope;
}
+void MozJSImplScope::setQuickExit(int exitCode) {
+ _quickExit = true;
+ _exitCode = exitCode;
+}
+
+bool MozJSImplScope::getQuickExit(int* exitCode) {
+ if (_quickExit) {
+ *exitCode = _exitCode;
+ }
+
+ return _quickExit;
+}
+
void MozJSImplScope::setOOM() {
_status = Status(ErrorCodes::JSInterpreterFailure, "Out of memory");
}
diff --git a/src/mongo/scripting/mozjs/implscope.h b/src/mongo/scripting/mozjs/implscope.h
index 4bd29e76676..6bd0c6c7411 100644
--- a/src/mongo/scripting/mozjs/implscope.h
+++ b/src/mongo/scripting/mozjs/implscope.h
@@ -226,6 +226,9 @@ public:
return _timestampProto;
}
+ void setQuickExit(int exitCode);
+ bool getQuickExit(int* exitCode);
+
static const char* const kExecResult;
static const char* const kInvokeResult;
@@ -291,6 +294,8 @@ private:
std::atomic<bool> _pendingGC;
ConnectState _connectState;
Status _status;
+ int _exitCode;
+ bool _quickExit;
WrapType<BinDataInfo> _binDataProto;
WrapType<BSONInfo> _bsonProto;
diff --git a/src/mongo/scripting/mozjs/mongo.cpp b/src/mongo/scripting/mozjs/mongo.cpp
index f1f69d0d39c..fe937e359dd 100644
--- a/src/mongo/scripting/mozjs/mongo.cpp
+++ b/src/mongo/scripting/mozjs/mongo.cpp
@@ -63,8 +63,8 @@ const JSFunctionSpec MongoBase::methods[13] = {
const char* const MongoBase::className = "Mongo";
-const JSFunctionSpec MongoExternalInfo::freeFunctions[2] = {
- MONGO_ATTACH_JS_FUNCTION(load), JS_FS_END,
+const JSFunctionSpec MongoExternalInfo::freeFunctions[3] = {
+ MONGO_ATTACH_JS_FUNCTION(load), MONGO_ATTACH_JS_FUNCTION(quit), JS_FS_END,
};
namespace {
@@ -561,5 +561,13 @@ void MongoExternalInfo::Functions::load(JSContext* cx, JS::CallArgs args) {
args.rval().setBoolean(true);
}
+void MongoExternalInfo::Functions::quit(JSContext* cx, JS::CallArgs args) {
+ auto scope = getScope(cx);
+
+ scope->setQuickExit(args.get(0).isNumber() ? args.get(0).toNumber() : 0);
+
+ uasserted(ErrorCodes::JSUncatchableError, "Calling Quit");
+}
+
} // namespace mozjs
} // namespace mongo
diff --git a/src/mongo/scripting/mozjs/mongo.h b/src/mongo/scripting/mozjs/mongo.h
index 35815da5455..e31e52fd14c 100644
--- a/src/mongo/scripting/mozjs/mongo.h
+++ b/src/mongo/scripting/mozjs/mongo.h
@@ -79,9 +79,10 @@ struct MongoExternalInfo : public MongoBase {
struct Functions {
MONGO_DEFINE_JS_FUNCTION(load);
+ MONGO_DEFINE_JS_FUNCTION(quit);
};
- static const JSFunctionSpec freeFunctions[2];
+ static const JSFunctionSpec freeFunctions[3];
};
} // namespace mozjs
diff --git a/src/mongo/scripting/mozjs/proxyscope.cpp b/src/mongo/scripting/mozjs/proxyscope.cpp
index 665d249f4c5..73e0a26d6f5 100644
--- a/src/mongo/scripting/mozjs/proxyscope.cpp
+++ b/src/mongo/scripting/mozjs/proxyscope.cpp
@@ -34,6 +34,7 @@
#include "mongo/db/operation_context.h"
#include "mongo/db/service_context.h"
#include "mongo/scripting/mozjs/implscope.h"
+#include "mongo/util/quick_exit.h"
namespace mongo {
namespace mozjs {
@@ -308,6 +309,12 @@ void MozJSProxyScope::implThread() {
_status = exceptionToStatus();
}
+ int exitCode;
+ if (_implScope && _implScope->getQuickExit(&exitCode)) {
+ scope.reset();
+ quickExit(exitCode);
+ }
+
_state = State::ImplResponse;
_condvar.notify_one();