summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Reams <jbreams@mongodb.com>2016-08-25 15:58:25 -0400
committerJonathan Reams <jbreams@mongodb.com>2017-05-04 15:26:27 -0400
commit317a3f627be5adf149d857a248d344342897e5f9 (patch)
tree385aaf653eb1148062e22fcaae872c8bbf69b341
parent4b949cc2b4bfb240f1fc67a500fc86de520fdf06 (diff)
downloadmongo-317a3f627be5adf149d857a248d344342897e5f9.tar.gz
SERVER-25764 Interrupt javascript periodically.
(cherry picked from commit 1875792bdc435c695aca1b6b57be7486e7df70c5)
-rw-r--r--src/mongo/scripting/deadline_monitor.h30
-rw-r--r--src/mongo/scripting/deadline_monitor_test.cpp1
-rw-r--r--src/mongo/scripting/mozjs/implscope.cpp18
-rw-r--r--src/mongo/scripting/mozjs/implscope.h2
-rw-r--r--src/mongo/scripting/mozjs/proxyscope.cpp4
-rw-r--r--src/mongo/scripting/mozjs/proxyscope.h2
6 files changed, 45 insertions, 12 deletions
diff --git a/src/mongo/scripting/deadline_monitor.h b/src/mongo/scripting/deadline_monitor.h
index 89f7e9d1b84..c4923e4aab9 100644
--- a/src/mongo/scripting/deadline_monitor.h
+++ b/src/mongo/scripting/deadline_monitor.h
@@ -91,11 +91,18 @@ public:
* @param task the task to kill()
* @param timeoutMs number of milliseconds before the deadline expires
*/
- void startDeadline(_Task* const task, uint64_t timeoutMs) {
- const auto deadline = Date_t::now() + Milliseconds(timeoutMs);
+ void startDeadline(_Task* const task, int64_t 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;
@@ -121,14 +128,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});
} else {
_newDeadlineAvailable.wait_until(lk,
_nearestDeadlineWallclock.toSystemTimePoint());
@@ -138,7 +147,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
@@ -152,10 +161,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 c5bd51ef5cd..70f76355202 100644
--- a/src/mongo/scripting/mozjs/implscope.cpp
+++ b/src/mongo/scripting/mozjs/implscope.cpp
@@ -169,6 +169,10 @@ void MozJSImplScope::kill() {
JS_RequestInterruptCallback(_runtime);
}
+void MozJSImplScope::interrupt() {
+ JS_RequestInterruptCallback(_runtime);
+}
+
bool MozJSImplScope::isKillPending() const {
return _pendingKill.load();
}
@@ -606,14 +610,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);
@@ -651,15 +657,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, _global, 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 3fac5e5bdef..48544aaf5b2 100644
--- a/src/mongo/scripting/mozjs/implscope.h
+++ b/src/mongo/scripting/mozjs/implscope.h
@@ -89,6 +89,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 5e48aabf9cf..2fd32ff6878 100644
--- a/src/mongo/scripting/mozjs/proxyscope.cpp
+++ b/src/mongo/scripting/mozjs/proxyscope.cpp
@@ -244,6 +244,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);