Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(706)

Unified Diff: third_party/WebKit/Source/core/workers/WorkerThread.cpp

Issue 2325923002: Worker: Factor out a part of WorkerThread::terminateInternal() into its own function for cleanup (Closed)
Patch Set: fix comments Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/workers/WorkerThread.cpp
diff --git a/third_party/WebKit/Source/core/workers/WorkerThread.cpp b/third_party/WebKit/Source/core/workers/WorkerThread.cpp
index d476d69a6b275249b76d5b896a0dea0cd7be7e79..9c58a3545d799b01847495ef26bb4eb3e22080cb 100644
--- a/third_party/WebKit/Source/core/workers/WorkerThread.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkerThread.cpp
@@ -59,6 +59,8 @@
namespace blink {
+using ExitCode = WorkerThread::ExitCode;
+
// TODO(nhiroki): Adjust the delay based on UMA.
const long long kForceTerminationDelayInMs = 2000; // 2 secs
@@ -103,8 +105,7 @@ private:
}
m_workerThread->forciblyTerminateExecution();
- DCHECK_EQ(WorkerThread::ExitCode::NotTerminated, m_workerThread->m_exitCode);
- m_workerThread->m_exitCode = WorkerThread::ExitCode::AsyncForciblyTerminated;
+ m_workerThread->setExitCode(lock, ExitCode::AsyncForciblyTerminated);
}
WorkerThread* m_workerThread;
@@ -398,8 +399,7 @@ void WorkerThread::terminateInternal(TerminationMode mode)
DCHECK(m_scheduledForceTerminationTask);
m_scheduledForceTerminationTask.reset();
forciblyTerminateExecution();
- DCHECK_EQ(ExitCode::NotTerminated, m_exitCode);
- m_exitCode = ExitCode::SyncForciblyTerminated;
+ setExitCode(lock, ExitCode::SyncForciblyTerminated);
}
return;
}
@@ -409,36 +409,18 @@ void WorkerThread::terminateInternal(TerminationMode mode)
// If the worker thread was never initialized, don't start another
// shutdown, but still wait for the thread to signal when shutdown
// has completed on initializeOnWorkerThread().
- DCHECK_EQ(ExitCode::NotTerminated, m_exitCode);
- m_exitCode = ExitCode::GracefullyTerminated;
- } else {
- // Determine if we should synchronously terminate or schedule to
- // terminate the worker execution so that the task can be handled
- // by thread event loop. If script execution weren't forbidden,
- // a while(1) loop in JS could keep the thread alive forever.
- //
- // (1) |m_threadState|: If this is ReadyToShutdown, the worker
- // thread has already noticed that the thread is about to be
- // terminated and the worker global scope is already disposed, so we
- // don't have to explicitly terminate the worker execution.
- //
- // (2) |m_runningDebuggerTask|: Terminating during debugger task
- // may lead to crash due to heavy use of v8 api in debugger. Any
- // debugger task is guaranteed to finish, so we can wait for the
- // completion.
- bool shouldScheduleToTerminateExecution = (m_threadState != ThreadState::ReadyToShutdown) && !m_runningDebuggerTask;
-
- if (shouldScheduleToTerminateExecution) {
- if (mode == TerminationMode::Forcible) {
- forciblyTerminateExecution();
- DCHECK_EQ(ExitCode::NotTerminated, m_exitCode);
- m_exitCode = ExitCode::SyncForciblyTerminated;
- } else {
- DCHECK_EQ(TerminationMode::Graceful, mode);
- DCHECK(!m_scheduledForceTerminationTask);
- m_scheduledForceTerminationTask = ForceTerminationTask::create(this);
- m_scheduledForceTerminationTask->schedule();
- }
+ setExitCode(lock, ExitCode::GracefullyTerminated);
+ } else if (shouldScheduleToTerminateExecution(lock)) {
+ switch (mode) {
+ case TerminationMode::Forcible:
+ forciblyTerminateExecution();
+ setExitCode(lock, ExitCode::SyncForciblyTerminated);
+ break;
+ case TerminationMode::Graceful:
+ DCHECK(!m_scheduledForceTerminationTask);
+ m_scheduledForceTerminationTask = ForceTerminationTask::create(this);
+ m_scheduledForceTerminationTask->schedule();
+ break;
}
}
}
@@ -452,6 +434,30 @@ void WorkerThread::terminateInternal(TerminationMode mode)
workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, crossThreadBind(&WorkerThread::performShutdownOnWorkerThread, crossThreadUnretained(this)));
}
+bool WorkerThread::shouldScheduleToTerminateExecution(const MutexLocker& lock)
+{
+ DCHECK(isMainThread());
+ DCHECK(isThreadStateMutexLocked(lock));
+
+ switch (m_threadState) {
+ case ThreadState::NotStarted:
+ // Shutdown sequence will surely start during initialization sequence
+ // on the worker thread. Don't have to schedule a termination task.
+ return false;
+ case ThreadState::Running:
+ // Terminating during debugger task may lead to crash due to heavy use
+ // of v8 api in debugger. Any debugger task is guaranteed to finish, so
+ // we can wait for the completion.
+ return !m_runningDebuggerTask;
+ case ThreadState::ReadyToShutdown:
+ // Shutdown sequence will surely start soon. Don't have to schedule a
+ // termination task.
+ return false;
+ }
+ NOTREACHED();
+ return false;
+}
+
void WorkerThread::forciblyTerminateExecution()
{
DCHECK(isMainThread());
@@ -531,7 +537,7 @@ void WorkerThread::initializeOnWorkerThread(std::unique_ptr<WorkerThreadStartupD
originTrialContext->initializePendingFeatures();
}
- m_threadState = ThreadState::Running;
+ setThreadState(lock, ThreadState::Running);
}
if (startMode == PauseWorkerGlobalScopeOnStart) {
@@ -566,9 +572,9 @@ void WorkerThread::prepareForShutdownOnWorkerThread()
MutexLocker lock(m_threadStateMutex);
if (m_threadState == ThreadState::ReadyToShutdown)
return;
- m_threadState = ThreadState::ReadyToShutdown;
+ setThreadState(lock, ThreadState::ReadyToShutdown);
if (m_exitCode == ExitCode::NotTerminated)
- m_exitCode = ExitCode::GracefullyTerminated;
+ setExitCode(lock, ExitCode::GracefullyTerminated);
}
m_inspectorTaskRunner->kill();
@@ -587,7 +593,7 @@ void WorkerThread::prepareForShutdownOnWorkerThread()
void WorkerThread::performShutdownOnWorkerThread()
{
DCHECK(isCurrentThread());
-#if DCHECK_IS_ON
+#if DCHECK_IS_ON()
{
MutexLocker lock(m_threadStateMutex);
DCHECK(m_requestedToTerminate);
@@ -668,7 +674,43 @@ void WorkerThread::performDebuggerTaskDontWaitOnWorkerThread()
(*task)();
}
-WorkerThread::ExitCode WorkerThread::getExitCodeForTesting()
+void WorkerThread::setThreadState(const MutexLocker& lock, ThreadState nextThreadState)
+{
+ DCHECK(isThreadStateMutexLocked(lock));
+ switch (nextThreadState) {
+ case ThreadState::NotStarted:
+ NOTREACHED();
+ return;
+ case ThreadState::Running:
+ DCHECK_EQ(ThreadState::NotStarted, m_threadState);
+ m_threadState = nextThreadState;
+ return;
+ case ThreadState::ReadyToShutdown:
+ DCHECK_EQ(ThreadState::Running, m_threadState);
+ m_threadState = nextThreadState;
+ return;
+ }
+}
+
+void WorkerThread::setExitCode(const MutexLocker& lock, ExitCode exitCode)
+{
+ DCHECK(isThreadStateMutexLocked(lock));
+ DCHECK_EQ(ExitCode::NotTerminated, m_exitCode);
+ m_exitCode = exitCode;
+}
+
+bool WorkerThread::isThreadStateMutexLocked(const MutexLocker& /* unused */)
+{
+#if ENABLE(ASSERT)
+ // Mutex::locked() is available only if ENABLE(ASSERT) is true.
+ return m_threadStateMutex.locked();
+#else
+ // Otherwise, believe the given MutexLocker holds |m_threadStateMutex|.
+ return true;
+#endif
+}
+
+ExitCode WorkerThread::getExitCodeForTesting()
{
MutexLocker lock(m_threadStateMutex);
return m_exitCode;
« no previous file with comments | « third_party/WebKit/Source/core/workers/WorkerThread.h ('k') | third_party/WebKit/Source/core/workers/WorkerThreadTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698