Reviewed by Darin Adler.
https://bugs.webkit.org/show_bug.cgi?id=22397
Worker threads are not destroyed if running a JS loop
Since the event loop is not ever entered again in this case, the fix necessarily involves
some shared data hackery.
* dom/WorkerThread.cpp: (WebCore::WorkerThread::stop):
* dom/WorkerThread.h:
Added a stop() method, which asks the thread to exit as soon as possible. In the future, it
may need to abort other kinds of synchronous processing, such as importScripts or XHR.
* bindings/js/WorkerScriptController.cpp:
(WebCore::WorkerScriptController::WorkerScriptController):
(WebCore::WorkerScriptController::evaluate):
(WebCore::WorkerScriptController::forbidExecution):
* bindings/js/WorkerScriptController.h:
Added a forbidExecution() method, which interrupts currently running JS, and makes any
future calls to evaluate() return immediately.
* dom/WorkerMessagingProxy.cpp: (WebCore::WorkerMessagingProxy::workerObjectDestroyed):
Call WorkerThread::stop().
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@38689 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/bindings/js/WorkerScriptController.cpp b/WebCore/bindings/js/WorkerScriptController.cpp
index a08dbc0..bbda011 100644
--- a/WebCore/bindings/js/WorkerScriptController.cpp
+++ b/WebCore/bindings/js/WorkerScriptController.cpp
@@ -35,6 +35,7 @@
#include "WorkerContext.h"
#include "WorkerMessagingProxy.h"
#include "WorkerThread.h"
+#include <interpreter/Interpreter.h>
#include <parser/SourceCode.h>
#include <runtime/Completion.h>
#include <runtime/Completion.h>
@@ -47,6 +48,7 @@
WorkerScriptController::WorkerScriptController(WorkerContext* workerContext)
: m_globalData(JSGlobalData::create())
, m_workerContext(workerContext)
+ , m_executionForbidded(false)
{
}
@@ -70,6 +72,12 @@
JSValue* WorkerScriptController::evaluate(const JSC::SourceCode& sourceCode)
{
+ {
+ MutexLocker lock(m_sharedDataMutex);
+ if (m_executionForbidded)
+ return noValue();
+ }
+
initScriptIfNeeded();
JSLock lock(false);
@@ -88,6 +96,17 @@
return noValue();
}
+void WorkerScriptController::forbidExecution()
+{
+ // This function is called from another thread.
+ // Mutex protection for m_executionForbidded is needed to guarantee that the value is synchronized between processors, because
+ // if it were not, the worker could re-enter JSC::evaluate(), but with timeout already reset.
+ // It is not critical for Interpreter::m_timeoutTime to be synchronized, we just rely on it reaching the worker thread's processor sooner or later.
+ MutexLocker lock(m_sharedDataMutex);
+ m_executionForbidded = true;
+ m_globalData->interpreter->setTimeoutTime(1); // 1 ms is the smallest timeout that can be set.
+}
+
} // namespace WebCore
#endif // ENABLE(WORKERS)