Chromium Code Reviews| 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 19 matching lines...) Expand all Loading... | |
| 30 #include <memory> | 30 #include <memory> |
| 31 | 31 |
| 32 #include "core/CoreExport.h" | 32 #include "core/CoreExport.h" |
| 33 #include "core/frame/csp/ContentSecurityPolicy.h" | 33 #include "core/frame/csp/ContentSecurityPolicy.h" |
| 34 #include "core/workers/ParentFrameTaskRunners.h" | 34 #include "core/workers/ParentFrameTaskRunners.h" |
| 35 #include "core/workers/WorkerLoaderProxy.h" | 35 #include "core/workers/WorkerLoaderProxy.h" |
| 36 #include "core/workers/WorkerThreadLifecycleObserver.h" | 36 #include "core/workers/WorkerThreadLifecycleObserver.h" |
| 37 #include "platform/LifecycleNotifier.h" | 37 #include "platform/LifecycleNotifier.h" |
| 38 #include "platform/WaitableEvent.h" | 38 #include "platform/WaitableEvent.h" |
| 39 #include "platform/WebTaskRunner.h" | 39 #include "platform/WebTaskRunner.h" |
| 40 #include "platform/scheduler/child/global_scope_scheduler.h" | |
| 40 #include "public/platform/WebThread.h" | 41 #include "public/platform/WebThread.h" |
| 41 #include "v8/include/v8.h" | 42 #include "v8/include/v8.h" |
| 42 #include "wtf/Forward.h" | 43 #include "wtf/Forward.h" |
| 43 #include "wtf/Functional.h" | 44 #include "wtf/Functional.h" |
| 44 #include "wtf/PassRefPtr.h" | 45 #include "wtf/PassRefPtr.h" |
| 45 | 46 |
| 46 namespace blink { | 47 namespace blink { |
| 47 | 48 |
| 48 class ConsoleMessageStorage; | 49 class ConsoleMessageStorage; |
| 49 class InspectorTaskRunner; | 50 class InspectorTaskRunner; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 85 // | 86 // |
| 86 // WorkerThread start and termination must be initiated on the main thread and | 87 // WorkerThread start and termination must be initiated on the main thread and |
| 87 // an actual task is executed on the worker thread. | 88 // an actual task is executed on the worker thread. |
| 88 // | 89 // |
| 89 // When termination starts, (debugger) tasks on WorkerThread are handled as | 90 // When termination starts, (debugger) tasks on WorkerThread are handled as |
| 90 // follows: | 91 // follows: |
| 91 // - A running task may finish unless a forcible termination task interrupts. | 92 // - A running task may finish unless a forcible termination task interrupts. |
| 92 // If the running task is for debugger, it's guaranteed to finish without | 93 // If the running task is for debugger, it's guaranteed to finish without |
| 93 // any interruptions. | 94 // any interruptions. |
| 94 // - Queued tasks never run. | 95 // - Queued tasks never run. |
| 95 // - postTask() and appendDebuggerTask() reject posting new tasks. | |
| 96 class CORE_EXPORT WorkerThread : public WebThread::TaskObserver { | 96 class CORE_EXPORT WorkerThread : public WebThread::TaskObserver { |
| 97 public: | 97 public: |
| 98 // Represents how this thread is terminated. Used for UMA. Append only. | 98 // Represents how this thread is terminated. Used for UMA. Append only. |
| 99 enum class ExitCode { | 99 enum class ExitCode { |
| 100 NotTerminated, | 100 NotTerminated, |
| 101 GracefullyTerminated, | 101 GracefullyTerminated, |
| 102 SyncForciblyTerminated, | 102 SyncForciblyTerminated, |
| 103 AsyncForciblyTerminated, | 103 AsyncForciblyTerminated, |
| 104 LastEnum, | 104 LastEnum, |
| 105 }; | 105 }; |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 130 | 130 |
| 131 WorkerLoaderProxy* workerLoaderProxy() const { | 131 WorkerLoaderProxy* workerLoaderProxy() const { |
| 132 RELEASE_ASSERT(m_workerLoaderProxy); | 132 RELEASE_ASSERT(m_workerLoaderProxy); |
| 133 return m_workerLoaderProxy.get(); | 133 return m_workerLoaderProxy.get(); |
| 134 } | 134 } |
| 135 | 135 |
| 136 WorkerReportingProxy& workerReportingProxy() const { | 136 WorkerReportingProxy& workerReportingProxy() const { |
| 137 return m_workerReportingProxy; | 137 return m_workerReportingProxy; |
| 138 } | 138 } |
| 139 | 139 |
| 140 void postTask(const WebTraceLocation&, std::unique_ptr<WTF::Closure>); | |
| 141 void postTask(const WebTraceLocation&, | |
| 142 std::unique_ptr<WTF::CrossThreadClosure>); | |
| 143 void appendDebuggerTask(std::unique_ptr<CrossThreadClosure>); | 140 void appendDebuggerTask(std::unique_ptr<CrossThreadClosure>); |
| 144 | 141 |
| 145 // Runs only debugger tasks while paused in debugger. | 142 // Runs only debugger tasks while paused in debugger. |
| 146 void startRunningDebuggerTasksOnPauseOnWorkerThread(); | 143 void startRunningDebuggerTasksOnPauseOnWorkerThread(); |
| 147 void stopRunningDebuggerTasksOnPauseOnWorkerThread(); | 144 void stopRunningDebuggerTasksOnPauseOnWorkerThread(); |
| 148 | 145 |
| 149 // Can be called only on the worker thread, WorkerOrWorkletGlobalScope | 146 // Can be called only on the worker thread, WorkerOrWorkletGlobalScope |
| 150 // and WorkerInspectorController are not thread safe. | 147 // and WorkerInspectorController are not thread safe. |
| 151 WorkerOrWorkletGlobalScope* globalScope(); | 148 WorkerOrWorkletGlobalScope* globalScope(); |
| 152 WorkerInspectorController* workerInspectorController(); | 149 WorkerInspectorController* workerInspectorController(); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 169 PlatformThreadId platformThreadId(); | 166 PlatformThreadId platformThreadId(); |
| 170 | 167 |
| 171 bool isForciblyTerminated(); | 168 bool isForciblyTerminated(); |
| 172 | 169 |
| 173 void waitForShutdownForTesting() { m_shutdownEvent->wait(); } | 170 void waitForShutdownForTesting() { m_shutdownEvent->wait(); } |
| 174 | 171 |
| 175 ParentFrameTaskRunners* getParentFrameTaskRunners() const { | 172 ParentFrameTaskRunners* getParentFrameTaskRunners() const { |
| 176 return m_parentFrameTaskRunners.get(); | 173 return m_parentFrameTaskRunners.get(); |
| 177 } | 174 } |
| 178 | 175 |
| 176 scheduler::GlobalScopeScheduler* globalScopeScheduler() const { | |
| 177 return m_globalScopeScheduler.get(); | |
| 178 } | |
| 179 | |
| 179 protected: | 180 protected: |
| 180 WorkerThread(PassRefPtr<WorkerLoaderProxy>, WorkerReportingProxy&); | 181 WorkerThread(PassRefPtr<WorkerLoaderProxy>, WorkerReportingProxy&); |
| 181 | 182 |
| 182 // Factory method for creating a new worker context for the thread. | 183 // Factory method for creating a new worker context for the thread. |
| 183 // Called on the worker thread. | 184 // Called on the worker thread. |
| 184 virtual WorkerOrWorkletGlobalScope* createWorkerGlobalScope( | 185 virtual WorkerOrWorkletGlobalScope* createWorkerGlobalScope( |
| 185 std::unique_ptr<WorkerThreadStartupData>) = 0; | 186 std::unique_ptr<WorkerThreadStartupData>) = 0; |
| 186 | 187 |
| 187 // Returns true when this WorkerThread owns the associated | 188 // Returns true when this WorkerThread owns the associated |
| 188 // WorkerBackingThread exclusively. If this function returns true, the | 189 // WorkerBackingThread exclusively. If this function returns true, the |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 236 // thread. This task is expected to run when the shutdown sequence does not | 237 // thread. This task is expected to run when the shutdown sequence does not |
| 237 // start in a certain time period because of an inifite loop in the JS | 238 // start in a certain time period because of an inifite loop in the JS |
| 238 // execution context etc. When the shutdown sequence is started before this | 239 // execution context etc. When the shutdown sequence is started before this |
| 239 // task runs, the task is simply cancelled. | 240 // task runs, the task is simply cancelled. |
| 240 void mayForciblyTerminateExecution(); | 241 void mayForciblyTerminateExecution(); |
| 241 | 242 |
| 242 // Forcibly terminates the worker execution. This must be called with | 243 // Forcibly terminates the worker execution. This must be called with |
| 243 // |m_threadStateMutex| acquired. | 244 // |m_threadStateMutex| acquired. |
| 244 void forciblyTerminateExecution(const MutexLocker&, ExitCode); | 245 void forciblyTerminateExecution(const MutexLocker&, ExitCode); |
| 245 | 246 |
| 246 // Returns true if termination or shutdown sequence has started. This is | 247 void initializeSchedulerOnWorkerThread(WaitableEvent*); |
| 247 // thread safe. | |
| 248 // Note that this returns false when the sequence has already started but it | |
| 249 // hasn't been notified to the calling thread. | |
| 250 bool isInShutdown(); | |
| 251 | |
| 252 void initializeOnWorkerThread(std::unique_ptr<WorkerThreadStartupData>); | 248 void initializeOnWorkerThread(std::unique_ptr<WorkerThreadStartupData>); |
| 253 void prepareForShutdownOnWorkerThread(); | 249 void prepareForShutdownOnWorkerThread(); |
| 254 void performShutdownOnWorkerThread(); | 250 void performShutdownOnWorkerThread(); |
| 255 template <WTF::FunctionThreadAffinity threadAffinity> | |
| 256 void performTaskOnWorkerThread( | |
| 257 std::unique_ptr<Function<void(), threadAffinity>> task); | |
| 258 void performDebuggerTaskOnWorkerThread(std::unique_ptr<CrossThreadClosure>); | 251 void performDebuggerTaskOnWorkerThread(std::unique_ptr<CrossThreadClosure>); |
| 259 void performDebuggerTaskDontWaitOnWorkerThread(); | 252 void performDebuggerTaskDontWaitOnWorkerThread(); |
| 260 | 253 |
| 261 // These must be called with |m_threadStateMutex| acquired. | 254 // These must be called with |m_threadStateMutex| acquired. |
| 262 void setThreadState(const MutexLocker&, ThreadState); | 255 void setThreadState(const MutexLocker&, ThreadState); |
| 263 void setExitCode(const MutexLocker&, ExitCode); | 256 void setExitCode(const MutexLocker&, ExitCode); |
| 264 bool isThreadStateMutexLocked(const MutexLocker&); | 257 bool isThreadStateMutexLocked(const MutexLocker&); |
| 265 | 258 |
| 266 // This internally acquires |m_threadStateMutex|. If you already have the | 259 // This internally acquires |m_threadStateMutex|. If you already have the |
| 267 // lock or you're on the main thread, you should consider directly accessing | 260 // lock or you're on the main thread, you should consider directly accessing |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 287 | 280 |
| 288 ThreadState m_threadState = ThreadState::NotStarted; | 281 ThreadState m_threadState = ThreadState::NotStarted; |
| 289 ExitCode m_exitCode = ExitCode::NotTerminated; | 282 ExitCode m_exitCode = ExitCode::NotTerminated; |
| 290 | 283 |
| 291 long long m_forcibleTerminationDelayInMs; | 284 long long m_forcibleTerminationDelayInMs; |
| 292 | 285 |
| 293 std::unique_ptr<InspectorTaskRunner> m_inspectorTaskRunner; | 286 std::unique_ptr<InspectorTaskRunner> m_inspectorTaskRunner; |
| 294 | 287 |
| 295 RefPtr<WorkerLoaderProxy> m_workerLoaderProxy; | 288 RefPtr<WorkerLoaderProxy> m_workerLoaderProxy; |
| 296 WorkerReportingProxy& m_workerReportingProxy; | 289 WorkerReportingProxy& m_workerReportingProxy; |
| 290 | |
| 297 CrossThreadPersistent<ParentFrameTaskRunners> m_parentFrameTaskRunners; | 291 CrossThreadPersistent<ParentFrameTaskRunners> m_parentFrameTaskRunners; |
| 298 | 292 |
| 293 // Per-global-scope scheduler. Tasks managed by this scheduler are canceled | |
| 294 // when the global scope is closed. | |
| 295 std::unique_ptr<scheduler::GlobalScopeScheduler> m_globalScopeScheduler; | |
|
Sami
2017/04/10 16:58:10
Would it make sense to call this a WorkerScheduler
nhiroki
2017/04/11 10:47:54
Current WorkerScheduler is a per-worker-thread obj
Sami
2017/04/11 11:52:02
Ah, I see. So you can have multiple global scopes
nhiroki
2017/04/12 08:54:45
Yes!
| |
| 296 | |
| 297 // Default task runner of the underlying thread. Tasks posted to this task | |
| 298 // runner will run even after the global scope is closed. This must be used | |
| 299 // only for control tasks. | |
| 300 RefPtr<WebTaskRunner> m_threadControlTaskRunner; | |
|
kinuko
2017/04/10 06:30:06
It feels a little confusing to have this and worke
nhiroki
2017/04/11 10:47:54
For now, I cannot come up with an idea to clean it
| |
| 301 | |
| 299 // This lock protects |m_globalScope|, |m_requestedToTerminate|, | 302 // This lock protects |m_globalScope|, |m_requestedToTerminate|, |
| 300 // |m_threadState|, |m_runningDebuggerTask| and |m_exitCode|. | 303 // |m_threadState|, |m_runningDebuggerTask| and |m_exitCode|. |
| 301 Mutex m_threadStateMutex; | 304 Mutex m_threadStateMutex; |
| 302 | 305 |
| 303 CrossThreadPersistent<ConsoleMessageStorage> m_consoleMessageStorage; | 306 CrossThreadPersistent<ConsoleMessageStorage> m_consoleMessageStorage; |
| 304 CrossThreadPersistent<WorkerOrWorkletGlobalScope> m_globalScope; | 307 CrossThreadPersistent<WorkerOrWorkletGlobalScope> m_globalScope; |
| 305 CrossThreadPersistent<WorkerInspectorController> m_workerInspectorController; | 308 CrossThreadPersistent<WorkerInspectorController> m_workerInspectorController; |
| 306 | 309 |
| 307 // Signaled when the thread completes termination on the worker thread. | 310 // Signaled when the thread completes termination on the worker thread. |
| 308 std::unique_ptr<WaitableEvent> m_shutdownEvent; | 311 std::unique_ptr<WaitableEvent> m_shutdownEvent; |
| 309 | 312 |
| 310 // Used to cancel a scheduled forcible termination task. See | 313 // Used to cancel a scheduled forcible termination task. See |
| 311 // mayForciblyTerminateExecution() for details. | 314 // mayForciblyTerminateExecution() for details. |
| 312 TaskHandle m_forcibleTerminationTaskHandle; | 315 TaskHandle m_forcibleTerminationTaskHandle; |
| 313 | 316 |
| 314 // Created on the main thread heap, but will be accessed cross-thread | 317 // Created on the main thread heap, but will be accessed cross-thread |
| 315 // when worker thread posts tasks. | 318 // when worker thread posts tasks. |
| 316 CrossThreadPersistent<WorkerThreadLifecycleContext> | 319 CrossThreadPersistent<WorkerThreadLifecycleContext> |
| 317 m_workerThreadLifecycleContext; | 320 m_workerThreadLifecycleContext; |
| 318 }; | 321 }; |
| 319 | 322 |
| 320 } // namespace blink | 323 } // namespace blink |
| 321 | 324 |
| 322 #endif // WorkerThread_h | 325 #endif // WorkerThread_h |
| OLD | NEW |