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

Side by Side Diff: third_party/WebKit/Source/core/workers/WorkerThread.cpp

Issue 2015823002: Worker: Stop calling Isolate::TerminateExecution() on a worker thread (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@reorder_functions
Patch Set: Created 4 years, 7 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 unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/core/workers/WorkerThread.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. 2 * Copyright (C) 2008 Apple Inc. All Rights Reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 // Signal the thread to notify that the thread's stopping. 136 // Signal the thread to notify that the thread's stopping.
137 if (m_terminationEvent) 137 if (m_terminationEvent)
138 m_terminationEvent->signal(); 138 m_terminationEvent->signal();
139 139
140 // If the worker thread was never initialized, don't start another 140 // If the worker thread was never initialized, don't start another
141 // shutdown, but still wait for the thread to signal when shutdown has 141 // shutdown, but still wait for the thread to signal when shutdown has
142 // completed on initializeOnWorkerThread(). 142 // completed on initializeOnWorkerThread().
143 if (!m_workerGlobalScope) 143 if (!m_workerGlobalScope)
144 return; 144 return;
145 145
146 if (!m_readyToShutdown) { 146 // Determine if we should terminate the isolate so that the task can
147 // Ensure that tasks are being handled by thread event loop. If script 147 // be handled by thread event loop. If script execution weren't forbidden,
148 // execution weren't forbidden, a while(1) loop in JS could keep the 148 // a while(1) loop in JS could keep the thread alive forever.
149 // thread alive forever. 149 //
150 // If |m_readyToShutdown| is set, the worker thread has already noticed 150 // (1) |m_readyToShutdown|: It this is set, the worker thread has already
151 // that the thread is about to be terminated and the worker global scope 151 // noticed that the thread is about to be terminated and the worker global
152 // is already disposed, so we don't have to explicitly terminate the 152 // scope is already disposed, so we don't have to explicitly terminate the
153 // execution. 153 // isolate.
154 //
155 // (2) |workerScriptCount() == 1|: If other WorkerGlobalScopes are running
156 // on the worker thread, we should not terminate the isolate. This condition
157 // is not entirely correct because other scripts can be being initialized or
158 // terminated simuletaneously. Though this function itself is protected by a
159 // mutex, it is possible that |workerScriptCount()| here is not consistent
160 // with that in |initialize| and |shutdown|.
161 //
162 // (3) |m_runningDebuggerTask|: Terminating during debugger task may lead to
163 // crash due to heavy use of v8 api in debugger. Any debugger task is
164 // guaranteed to finish, so we can wait for the completion.
165 bool shouldTerminateIsolate = !m_readyToShutdown && (workerBackingThread().w orkerScriptCount() == 1) && !m_runningDebuggerTask;
166
167 if (shouldTerminateIsolate) {
168 // TODO(yhirano): TerminateExecution should be called more
169 // carefully (https://crbug.com/413518).
154 m_workerGlobalScope->scriptController()->willScheduleExecutionTerminatio n(); 170 m_workerGlobalScope->scriptController()->willScheduleExecutionTerminatio n();
155 171 isolate()->TerminateExecution();
156 // This condition is not entirely correct because other scripts can
157 // be being initialized or terminated simuletaneously. Though this
158 // function itself is protected by a mutex, it is possible that
159 // |workerScriptCount()| here is not consistent with that in
160 // |initialize| and |shutdown|.
161 if (workerBackingThread().workerScriptCount() == 1) {
162 if (m_runningDebuggerTask) {
163 // Terminating during debugger task may lead to crash due to
164 // heavy use of v8 api in debugger. Any debugger task is
165 // guaranteed to finish, so we can postpone termination after
166 // task has finished.
167 // Note: m_runningDebuggerTask and m_shouldTerminateV8Execution
168 // access must be guarded by the lock.
169 m_shouldTerminateV8Execution = true;
170 } else {
171 // TODO(yhirano): TerminateExecution should be called more
172 // carefully (https://crbug.com/413518).
173 isolate()->TerminateExecution();
174 }
175 }
176 } 172 }
177 173
178 m_inspectorTaskRunner->kill(); 174 m_inspectorTaskRunner->kill();
179 workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBi nd(&WorkerThread::prepareForShutdownOnWorkerThread, AllowCrossThreadAccess(this) )); 175 workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBi nd(&WorkerThread::prepareForShutdownOnWorkerThread, AllowCrossThreadAccess(this) ));
180 workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBi nd(&WorkerThread::performShutdownOnWorkerThread, AllowCrossThreadAccess(this))); 176 workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBi nd(&WorkerThread::performShutdownOnWorkerThread, AllowCrossThreadAccess(this)));
181 } 177 }
182 178
183 void WorkerThread::terminateAndWait() 179 void WorkerThread::terminateAndWait()
184 { 180 {
185 DCHECK(isMainThread()); 181 DCHECK(isMainThread());
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 { 437 {
442 MutexLocker lock(m_threadStateMutex); 438 MutexLocker lock(m_threadStateMutex);
443 m_runningDebuggerTask = true; 439 m_runningDebuggerTask = true;
444 } 440 }
445 ThreadDebugger::idleFinished(isolate()); 441 ThreadDebugger::idleFinished(isolate());
446 (*task)(); 442 (*task)();
447 ThreadDebugger::idleStarted(isolate()); 443 ThreadDebugger::idleStarted(isolate());
448 { 444 {
449 MutexLocker lock(m_threadStateMutex); 445 MutexLocker lock(m_threadStateMutex);
450 m_runningDebuggerTask = false; 446 m_runningDebuggerTask = false;
451 if (m_shouldTerminateV8Execution) { 447
452 m_shouldTerminateV8Execution = false; 448 if (!m_terminated)
453 isolate()->TerminateExecution(); 449 return;
454 } 450 // terminate() was called. Shutdown sequence will start soon.
451
452 if (m_readyToShutdown)
453 return;
454 // Disposes WorkerGlobalScope to stop associated ActiveDOMObjects and
455 // close the event queue.
456 prepareForShutdownOnWorkerThread();
yhirano 2016/05/26 07:57:38 m_threadStateMutex is not recursive, so you should
yhirano 2016/05/26 07:57:38 I'm not sure why this is needed, because we've alr
nhiroki 2016/05/26 08:13:52 Good point. Moved this to out of the critical sect
nhiroki 2016/05/26 08:13:52 Other tasks that may block the worker thread could
455 } 457 }
456 } 458 }
457 459
458 void WorkerThread::runDebuggerTaskDontWaitOnWorkerThread() 460 void WorkerThread::runDebuggerTaskDontWaitOnWorkerThread()
459 { 461 {
460 DCHECK(isCurrentThread()); 462 DCHECK(isCurrentThread());
461 std::unique_ptr<CrossThreadClosure> task = m_inspectorTaskRunner->takeNextTa sk(InspectorTaskRunner::DontWaitForTask); 463 std::unique_ptr<CrossThreadClosure> task = m_inspectorTaskRunner->takeNextTa sk(InspectorTaskRunner::DontWaitForTask);
462 if (task) 464 if (task)
463 (*task)(); 465 (*task)();
464 } 466 }
465 467
466 } // namespace blink 468 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/workers/WorkerThread.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698