diff options
author | Jonathan Reams <jbreams@mongodb.com> | 2016-08-25 15:58:25 -0400 |
---|---|---|
committer | Jonathan Reams <jbreams@mongodb.com> | 2016-08-29 17:15:34 -0400 |
commit | 1875792bdc435c695aca1b6b57be7486e7df70c5 (patch) | |
tree | 5251a72001f194e0599ceeb7d9bf4208f6c54b70 /src/mongo/scripting | |
parent | bdf345a78764d2552373b5f938ac9aa6be5346b9 (diff) | |
download | mongo-1875792bdc435c695aca1b6b57be7486e7df70c5.tar.gz |
SERVER-25764 Interrupt javascript periodically.
Diffstat (limited to 'src/mongo/scripting')
-rw-r--r-- | src/mongo/scripting/deadline_monitor.h | 28 | ||||
-rw-r--r-- | src/mongo/scripting/deadline_monitor_test.cpp | 1 | ||||
-rw-r--r-- | src/mongo/scripting/mozjs/implscope.cpp | 18 | ||||
-rw-r--r-- | src/mongo/scripting/mozjs/implscope.h | 2 | ||||
-rw-r--r-- | src/mongo/scripting/mozjs/proxyscope.cpp | 4 | ||||
-rw-r--r-- | src/mongo/scripting/mozjs/proxyscope.h | 2 |
6 files changed, 44 insertions, 11 deletions
diff --git a/src/mongo/scripting/deadline_monitor.h b/src/mongo/scripting/deadline_monitor.h index d3c30f4b2e8..9a68b78e60f 100644 --- a/src/mongo/scripting/deadline_monitor.h +++ b/src/mongo/scripting/deadline_monitor.h @@ -93,10 +93,17 @@ public: * @param timeoutMs number of milliseconds before the deadline expires */ void startDeadline(_Task* const task, int64_t timeoutMs) { - const auto deadline = Date_t::now() + Milliseconds(timeoutMs); + Date_t deadline; + if (timeoutMs > 0) { + deadline = Date_t::now() + Milliseconds(timeoutMs); + } else { + deadline = Date_t::max(); + } stdx::lock_guard<stdx::mutex> lk(_deadlineMutex); - _tasks[task] = deadline; + if (_tasks.find(task) == _tasks.end()) { + _tasks.emplace(task, deadline); + } if (deadline < _nearestDeadlineWallclock) { _nearestDeadlineWallclock = deadline; @@ -122,14 +129,16 @@ private: */ void deadlineMonitorThread() { stdx::unique_lock<stdx::mutex> lk(_deadlineMutex); + Date_t lastInterruptCycle = Date_t::now(); while (!_inShutdown) { // get the next interval to wait const Date_t now = Date_t::now(); // wait for a task to be added or a deadline to expire if (_nearestDeadlineWallclock > now) { - if (_nearestDeadlineWallclock == Date_t::max()) { - _newDeadlineAvailable.wait(lk); + if (_nearestDeadlineWallclock == Date_t::max() || + _nearestDeadlineWallclock - now > Seconds{1}) { + _newDeadlineAvailable.wait_for(lk, Seconds{1}.toSystemDuration()); } else { _newDeadlineAvailable.wait_until(lk, _nearestDeadlineWallclock.toSystemTimePoint()); @@ -139,7 +148,7 @@ private: // set the next interval to wait for deadline completion _nearestDeadlineWallclock = Date_t::max(); - typename TaskDeadlineMap::iterator i = _tasks.begin(); + auto i = _tasks.begin(); while (i != _tasks.end()) { if (i->second < now) { // deadline expired @@ -153,10 +162,17 @@ private: ++i; } } + + if (now - lastInterruptCycle > Seconds{1}) { + for (auto it : _tasks) { + it.first->interrupt(); + } + lastInterruptCycle = now; + } } } - typedef unordered_map<_Task*, Date_t> TaskDeadlineMap; + using TaskDeadlineMap = std::unordered_map<_Task*, Date_t>; TaskDeadlineMap _tasks; // map of running tasks with deadlines stdx::mutex _deadlineMutex; // protects all non-const members, except _monitorThread stdx::condition_variable _newDeadlineAvailable; // Signaled for timeout, start and stop diff --git a/src/mongo/scripting/deadline_monitor_test.cpp b/src/mongo/scripting/deadline_monitor_test.cpp index 98f4008b234..71daefbce8f 100644 --- a/src/mongo/scripting/deadline_monitor_test.cpp +++ b/src/mongo/scripting/deadline_monitor_test.cpp @@ -72,6 +72,7 @@ public: if (_group) _group->noteKill(); } + void interrupt() {} TaskGroup* _group; uint64_t _killed; }; diff --git a/src/mongo/scripting/mozjs/implscope.cpp b/src/mongo/scripting/mozjs/implscope.cpp index c808a88875f..3a8fb1e2d18 100644 --- a/src/mongo/scripting/mozjs/implscope.cpp +++ b/src/mongo/scripting/mozjs/implscope.cpp @@ -179,6 +179,10 @@ void MozJSImplScope::kill() { JS_RequestInterruptCallback(_runtime); } +void MozJSImplScope::interrupt() { + JS_RequestInterruptCallback(_runtime); +} + bool MozJSImplScope::isKillPending() const { return _pendingKill.load(); } @@ -635,14 +639,16 @@ int MozJSImplScope::invoke(ScriptingFunction func, if (timeoutMs) _engine->getDeadlineMonitor().startDeadline(this, timeoutMs); + else { + _engine->getDeadlineMonitor().startDeadline(this, -1); + } JS::RootedValue out(_context); JS::RootedObject obj(_context, smrecv.toObjectOrNull()); bool success = JS::Call(_context, obj, funcValue, args, &out); - if (timeoutMs) - _engine->getDeadlineMonitor().stopDeadline(this); + _engine->getDeadlineMonitor().stopDeadline(this); _checkErrorState(success); @@ -680,15 +686,17 @@ bool MozJSImplScope::exec(StringData code, if (_checkErrorState(success, reportError, assertOnError)) return false; - if (timeoutMs) + if (timeoutMs) { _engine->getDeadlineMonitor().startDeadline(this, timeoutMs); + } else { + _engine->getDeadlineMonitor().startDeadline(this, -1); + } JS::RootedValue out(_context); success = JS_ExecuteScript(_context, script, &out); - if (timeoutMs) - _engine->getDeadlineMonitor().stopDeadline(this); + _engine->getDeadlineMonitor().stopDeadline(this); if (_checkErrorState(success, reportError, assertOnError)) return false; diff --git a/src/mongo/scripting/mozjs/implscope.h b/src/mongo/scripting/mozjs/implscope.h index 080716428ac..d34921578b7 100644 --- a/src/mongo/scripting/mozjs/implscope.h +++ b/src/mongo/scripting/mozjs/implscope.h @@ -90,6 +90,8 @@ public: void kill(); + void interrupt(); + bool isKillPending() const override; OperationContext* getOpContext() const; diff --git a/src/mongo/scripting/mozjs/proxyscope.cpp b/src/mongo/scripting/mozjs/proxyscope.cpp index d5233f8379d..cf41e84091c 100644 --- a/src/mongo/scripting/mozjs/proxyscope.cpp +++ b/src/mongo/scripting/mozjs/proxyscope.cpp @@ -245,6 +245,10 @@ void MozJSProxyScope::kill() { _implScope->kill(); } +void MozJSProxyScope::interrupt() { + _implScope->interrupt(); +} + /** * Invokes a function on the implementation thread * diff --git a/src/mongo/scripting/mozjs/proxyscope.h b/src/mongo/scripting/mozjs/proxyscope.h index 09a84101dfd..d19e24149bd 100644 --- a/src/mongo/scripting/mozjs/proxyscope.h +++ b/src/mongo/scripting/mozjs/proxyscope.h @@ -175,6 +175,8 @@ public: */ void kill(); + void interrupt(); + private: template <typename Closure> void run(Closure&& closure); |