diff options
author | Max Hirschhorn <max.hirschhorn@mongodb.com> | 2014-11-14 18:00:52 -0500 |
---|---|---|
committer | Max Hirschhorn <max.hirschhorn@mongodb.com> | 2014-11-17 16:39:48 -0500 |
commit | 09d04e84e71651a5af7fa738c4614a6dd4dfb848 (patch) | |
tree | fce906bdd6634533a0681013b9398b0e6887ecb9 | |
parent | 5b032a9c80e483b6e28a2d6727cbc990de203cd4 (diff) | |
download | mongo-09d04e84e71651a5af7fa738c4614a6dd4dfb848.tar.gz |
SERVER-16190 Add hasFailed() function to JSThreadConfig.
Allows the caller to detect if the JSThread has thrown a JS or C++
exception, without calling join() on the thread.
-rw-r--r-- | src/mongo/scripting/v8_utils.cpp | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/src/mongo/scripting/v8_utils.cpp b/src/mongo/scripting/v8_utils.cpp index 05ce1728552..3cdff855a7d 100644 --- a/src/mongo/scripting/v8_utils.cpp +++ b/src/mongo/scripting/v8_utils.cpp @@ -101,6 +101,7 @@ namespace mongo { JSThreadConfig(V8Scope* scope, const v8::Arguments& args, bool newScope = false) : _started(), _done(), + _errored(), _newScope(newScope) { jsassert(args.Length() > 0, "need at least one argument"); jsassert(args[0]->IsFunction(), "first argument must be a function"); @@ -128,6 +129,16 @@ namespace mongo { _done = true; } + /** + * Returns true if the JSThread terminated as a result of an error + * during its execution, and false otherwise. This operation does + * not block, nor does it require join() to have been called. + */ + bool hasFailed() const { + jsassert(_started, "Thread not started"); + return _errored; + } + BSONObj returnData() { if (!_done) join(); @@ -168,8 +179,7 @@ namespace mongo { string e = _config._scope->v8ExceptionToSTLString(&try_catch); log() << "js thread raised js exception: " << e << endl; ret = v8::Undefined(); - // TODO propagate exceptions (or at least the fact that an exception was - // thrown) to the calling js on either join() or returnData(). + _config._errored = true; } // ret is translated to BSON to switch isolate BSONObjBuilder b; @@ -179,14 +189,17 @@ namespace mongo { catch (const DBException& e) { // Keeping behavior the same as for js exceptions. log() << "js thread threw c++ exception: " << e.toString(); + _config._errored = true; _config._returnData = BSON("ret" << BSONUndefined); } catch (const std::exception& e) { log() << "js thread threw c++ exception: " << e.what(); + _config._errored = true; _config._returnData = BSON("ret" << BSONUndefined); } catch (...) { log() << "js thread threw c++ non-exception"; + _config._errored = true; _config._returnData = BSON("ret" << BSONUndefined); } } @@ -197,6 +210,7 @@ namespace mongo { bool _started; bool _done; + bool _errored; bool _newScope; BSONObj _args; scoped_ptr<boost::thread> _thread; @@ -241,6 +255,12 @@ namespace mongo { return v8::Undefined(); } + // Indicates to the caller that the thread terminated as a result of an error. + v8::Handle<v8::Value> ThreadHasFailed(V8Scope* scope, const v8::Arguments& args) { + bool hasFailed = thisConfig(scope, args)->hasFailed(); + return v8::Boolean::New(hasFailed); + } + v8::Handle<v8::Value> ThreadReturnData(V8Scope* scope, const v8::Arguments& args) { BSONObj data = thisConfig(scope, args)->returnData(); return scope->mongoToV8Element(data.firstElement(), true); @@ -256,6 +276,7 @@ namespace mongo { scope->injectV8Function("init", ThreadInit, o); scope->injectV8Function("start", ThreadStart, o); scope->injectV8Function("join", ThreadJoin, o); + scope->injectV8Function("hasFailed", ThreadHasFailed, o); scope->injectV8Function("returnData", ThreadReturnData, o); return handle_scope.Close(v8::Handle<v8::Value>()); } |