OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |