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 17 matching lines...) Expand all Loading... | |
28 | 28 |
29 #include "core/workers/WorkerThread.h" | 29 #include "core/workers/WorkerThread.h" |
30 | 30 |
31 #include "bindings/core/v8/ScriptSourceCode.h" | 31 #include "bindings/core/v8/ScriptSourceCode.h" |
32 #include "core/inspector/InspectorInstrumentation.h" | 32 #include "core/inspector/InspectorInstrumentation.h" |
33 #include "core/workers/DedicatedWorkerGlobalScope.h" | 33 #include "core/workers/DedicatedWorkerGlobalScope.h" |
34 #include "core/workers/WorkerClients.h" | 34 #include "core/workers/WorkerClients.h" |
35 #include "core/workers/WorkerReportingProxy.h" | 35 #include "core/workers/WorkerReportingProxy.h" |
36 #include "core/workers/WorkerThreadStartupData.h" | 36 #include "core/workers/WorkerThreadStartupData.h" |
37 #include "platform/PlatformThreadData.h" | 37 #include "platform/PlatformThreadData.h" |
38 #include "platform/Task.h" | |
39 #include "platform/ThreadTimers.h" | |
38 #include "platform/heap/ThreadState.h" | 40 #include "platform/heap/ThreadState.h" |
39 #include "platform/weborigin/KURL.h" | 41 #include "platform/weborigin/KURL.h" |
40 #include "public/platform/Platform.h" | 42 #include "public/platform/Platform.h" |
43 #include "public/platform/WebThread.h" | |
41 #include "public/platform/WebWaitableEvent.h" | 44 #include "public/platform/WebWaitableEvent.h" |
42 #include "public/platform/WebWorkerRunLoop.h" | 45 #include "public/platform/WebWorkerRunLoop.h" |
43 #include "wtf/Noncopyable.h" | 46 #include "wtf/Noncopyable.h" |
44 #include "wtf/text/WTFString.h" | 47 #include "wtf/text/WTFString.h" |
45 | 48 |
46 #include <utility> | 49 #include <utility> |
47 | 50 |
48 namespace blink { | 51 namespace blink { |
49 | 52 |
53 namespace { | |
54 const int64 kShortIdleHandlerDelayMs = 1000; | |
55 const int64 kLongIdleHandlerDelayMs = 10*1000; | |
56 } | |
57 | |
50 static Mutex& threadSetMutex() | 58 static Mutex& threadSetMutex() |
51 { | 59 { |
52 AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex); | 60 AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex); |
53 return mutex; | 61 return mutex; |
54 } | 62 } |
55 | 63 |
56 static HashSet<WorkerThread*>& workerThreads() | 64 static HashSet<WorkerThread*>& workerThreads() |
57 { | 65 { |
58 DEFINE_STATIC_LOCAL(HashSet<WorkerThread*>, threads, ()); | 66 DEFINE_STATIC_LOCAL(HashSet<WorkerThread*>, threads, ()); |
59 return threads; | 67 return threads; |
60 } | 68 } |
61 | 69 |
62 unsigned WorkerThread::workerThreadCount() | 70 unsigned WorkerThread::workerThreadCount() |
63 { | 71 { |
64 MutexLocker lock(threadSetMutex()); | 72 MutexLocker lock(threadSetMutex()); |
65 return workerThreads().size(); | 73 return workerThreads().size(); |
66 } | 74 } |
67 | 75 |
76 class WorkerSharedTimer : public SharedTimer { | |
77 public: | |
78 WorkerSharedTimer(blink::WebThread* web_thread) | |
jochen (gone - plz use gerrit)
2014/07/24 12:12:33
explicit and webThread
nasko
2014/07/24 12:53:18
Done.
| |
79 : m_thread(web_thread) | |
80 , m_nextFireTime(0.0) | |
81 { } | |
82 | |
83 virtual void setFiredFunction(blink::WebThread::SharedTimerFunction func) | |
84 { | |
85 if (m_thread) | |
jochen (gone - plz use gerrit)
2014/07/24 12:12:33
when can m_thread be null?
nasko
2014/07/24 12:53:18
Shouldn't be null.
| |
86 m_thread->setSharedTimerFiredFunction(func); | |
87 else | |
88 m_nextFireTime = 0.0; | |
89 } | |
90 virtual void setFireInterval(double interval) | |
91 { | |
92 if (m_thread) | |
93 m_thread->setSharedTimerFireInterval(interval); | |
94 m_nextFireTime = interval + currentTime(); | |
95 } | |
96 virtual void stop() | |
97 { | |
98 if (m_thread) | |
99 m_thread->stopSharedTimer(); | |
100 } | |
101 | |
102 double nextFireTime() { return m_nextFireTime; } | |
103 | |
104 private: | |
105 blink::WebThread* m_thread; | |
106 double m_nextFireTime; | |
107 }; | |
108 | |
109 class WorkerThreadTask : public blink::WebThread::Task { | |
110 WTF_MAKE_NONCOPYABLE(WorkerThreadTask); WTF_MAKE_FAST_ALLOCATED; | |
111 public: | |
112 static PassOwnPtr<WorkerThreadTask> create(const WorkerThread& workerThread, PassOwnPtr<ExecutionContextTask> task, bool isInstrumented) | |
113 { | |
114 return adoptPtr(new WorkerThreadTask(workerThread, task, isInstrumented) ); | |
115 } | |
116 | |
117 virtual ~WorkerThreadTask() { } | |
118 | |
119 virtual void run() OVERRIDE | |
120 { | |
121 WorkerGlobalScope* workerGlobalScope = m_workerThread.workerGlobalScope( ); | |
122 if (m_isInstrumented) | |
123 InspectorInstrumentation::willPerformExecutionContextTask(workerGlob alScope, m_task.get()); | |
124 if ((!workerGlobalScope->isClosing() && !m_workerThread.terminated()) || m_task->isCleanupTask()) | |
125 m_task->performTask(workerGlobalScope); | |
126 if (m_isInstrumented) | |
127 InspectorInstrumentation::didPerformExecutionContextTask(workerGloba lScope); | |
128 } | |
129 | |
130 private: | |
131 WorkerThreadTask(const WorkerThread& workerThread, PassOwnPtr<ExecutionConte xtTask> task, bool isInstrumented) | |
132 : m_workerThread(workerThread) | |
133 , m_task(task) | |
134 , m_isInstrumented(isInstrumented) | |
135 { | |
136 if (m_isInstrumented) | |
137 m_isInstrumented = !m_task->taskNameForInstrumentation().isEmpty(); | |
138 if (m_isInstrumented) | |
139 InspectorInstrumentation::didPostExecutionContextTask(m_workerThread .workerGlobalScope(), m_task.get()); | |
140 } | |
141 | |
142 const WorkerThread& m_workerThread; | |
143 OwnPtr<ExecutionContextTask> m_task; | |
144 bool m_isInstrumented; | |
145 }; | |
146 | |
147 class RunDebuggerQueueTask FINAL : public ExecutionContextTask { | |
148 public: | |
149 static PassOwnPtr<RunDebuggerQueueTask> create(WorkerThread* thread) | |
150 { | |
151 return adoptPtr(new RunDebuggerQueueTask(thread)); | |
152 } | |
153 virtual void performTask(ExecutionContext* context) OVERRIDE | |
154 { | |
155 ASSERT(context->isWorkerGlobalScope()); | |
156 m_thread->runDebuggerTask(WorkerThread::DontWaitForMessage); | |
157 } | |
158 | |
159 private: | |
160 explicit RunDebuggerQueueTask(WorkerThread* thread) : m_thread(thread) { } | |
161 | |
162 WorkerThread* m_thread; | |
163 }; | |
164 | |
68 WorkerThread::WorkerThread(WorkerLoaderProxy& workerLoaderProxy, WorkerReporting Proxy& workerReportingProxy, PassOwnPtrWillBeRawPtr<WorkerThreadStartupData> sta rtupData) | 165 WorkerThread::WorkerThread(WorkerLoaderProxy& workerLoaderProxy, WorkerReporting Proxy& workerReportingProxy, PassOwnPtrWillBeRawPtr<WorkerThreadStartupData> sta rtupData) |
69 : m_threadID(0) | 166 : m_terminated(false) |
70 , m_workerLoaderProxy(workerLoaderProxy) | 167 , m_workerLoaderProxy(workerLoaderProxy) |
71 , m_workerReportingProxy(workerReportingProxy) | 168 , m_workerReportingProxy(workerReportingProxy) |
72 , m_startupData(startupData) | 169 , m_startupData(startupData) |
73 , m_shutdownEvent(adoptPtr(blink::Platform::current()->createWaitableEvent() )) | 170 , m_shutdownEvent(adoptPtr(blink::Platform::current()->createWaitableEvent() )) |
74 { | 171 { |
75 MutexLocker lock(threadSetMutex()); | 172 MutexLocker lock(threadSetMutex()); |
76 workerThreads().add(this); | 173 workerThreads().add(this); |
77 } | 174 } |
78 | 175 |
79 WorkerThread::~WorkerThread() | 176 WorkerThread::~WorkerThread() |
80 { | 177 { |
81 MutexLocker lock(threadSetMutex()); | 178 MutexLocker lock(threadSetMutex()); |
82 ASSERT(workerThreads().contains(this)); | 179 ASSERT(workerThreads().contains(this)); |
83 workerThreads().remove(this); | 180 workerThreads().remove(this); |
84 } | 181 } |
85 | 182 |
86 bool WorkerThread::start() | 183 void WorkerThread::start() |
87 { | 184 { |
88 // Mutex protection is necessary to ensure that m_threadID is initialized wh en the thread starts. | 185 if (m_thread) |
89 MutexLocker lock(m_threadCreationMutex); | 186 return; |
90 | 187 |
91 if (m_threadID) | 188 m_thread = adoptPtr(blink::Platform::current()->createThread("WebCore: Worke r")); |
92 return true; | 189 m_sharedTimer = adoptPtr(new WorkerSharedTimer(m_thread.get())); |
93 | 190 m_thread->postTask(new Task(WTF::bind(&WorkerThread::initialize, this))); |
94 m_threadID = createThread(WorkerThread::workerThreadStart, this, "WebCore: W orker"); | |
95 | |
96 return m_threadID; | |
97 } | 191 } |
98 | 192 |
99 void WorkerThread::workerThreadStart(void* thread) | 193 void WorkerThread::initialize() |
100 { | |
101 static_cast<WorkerThread*>(thread)->workerThread(); | |
102 } | |
103 | |
104 void WorkerThread::workerThread() | |
105 { | 194 { |
106 KURL scriptURL = m_startupData->m_scriptURL; | 195 KURL scriptURL = m_startupData->m_scriptURL; |
107 String sourceCode = m_startupData->m_sourceCode; | 196 String sourceCode = m_startupData->m_sourceCode; |
108 WorkerThreadStartMode startMode = m_startupData->m_startMode; | 197 WorkerThreadStartMode startMode = m_startupData->m_startMode; |
109 | 198 |
110 { | 199 { |
111 MutexLocker lock(m_threadCreationMutex); | 200 MutexLocker lock(m_threadCreationMutex); |
201 | |
112 ThreadState::attach(); | 202 ThreadState::attach(); |
113 m_workerGlobalScope = createWorkerGlobalScope(m_startupData.release()); | 203 m_workerGlobalScope = createWorkerGlobalScope(m_startupData.release()); |
114 m_runLoop.setWorkerGlobalScope(workerGlobalScope()); | |
115 | 204 |
116 if (m_runLoop.terminated()) { | 205 PlatformThreadData::current().threadTimers().setSharedTimer(m_sharedTime r.get()); |
206 | |
207 if (m_terminated) { | |
117 // The worker was terminated before the thread had a chance to run. Since the context didn't exist yet, | 208 // The worker was terminated before the thread had a chance to run. Since the context didn't exist yet, |
118 // forbidExecution() couldn't be called from stop(). | 209 // forbidExecution() couldn't be called from stop(). |
119 m_workerGlobalScope->script()->forbidExecution(); | 210 m_workerGlobalScope->script()->forbidExecution(); |
120 } | 211 } |
121 } | 212 } |
122 // The corresponding call to didStopWorkerRunLoop is in | 213 |
214 // The corresponding call to didStopWorkerThread is in | |
123 // ~WorkerScriptController. | 215 // ~WorkerScriptController. |
124 blink::Platform::current()->didStartWorkerRunLoop(blink::WebWorkerRunLoop(&m _runLoop)); | 216 blink::Platform::current()->didStartWorkerThread(m_thread.get()); |
125 | 217 |
126 // Notify proxy that a new WorkerGlobalScope has been created and started. | 218 // Notify proxy that a new WorkerGlobalScope has been created and started. |
127 m_workerReportingProxy.workerGlobalScopeStarted(m_workerGlobalScope.get()); | 219 m_workerReportingProxy.workerGlobalScopeStarted(m_workerGlobalScope.get()); |
128 | 220 |
129 WorkerScriptController* script = m_workerGlobalScope->script(); | 221 WorkerScriptController* script = m_workerGlobalScope->script(); |
130 if (!script->isExecutionForbidden()) | 222 if (!script->isExecutionForbidden()) |
131 script->initializeContextIfNeeded(); | 223 script->initializeContextIfNeeded(); |
132 InspectorInstrumentation::willEvaluateWorkerScript(workerGlobalScope(), star tMode); | 224 InspectorInstrumentation::willEvaluateWorkerScript(workerGlobalScope(), star tMode); |
133 script->evaluate(ScriptSourceCode(sourceCode, scriptURL)); | 225 script->evaluate(ScriptSourceCode(sourceCode, scriptURL)); |
134 | 226 |
135 runEventLoop(); | 227 postInitialize(); |
228 | |
229 m_weakFactory = adoptPtr(new WeakPtrFactory<WorkerThread>(this)); | |
230 m_thread->postDelayedTask(new Task(WTF::bind(&WorkerThread::idleHandler, m_w eakFactory->createWeakPtr())), kShortIdleHandlerDelayMs); | |
231 } | |
232 | |
233 void WorkerThread::cleanup() | |
234 { | |
235 m_weakFactory.release(); | |
136 | 236 |
137 // This should be called before we start the shutdown procedure. | 237 // This should be called before we start the shutdown procedure. |
138 workerReportingProxy().willDestroyWorkerGlobalScope(); | 238 workerReportingProxy().willDestroyWorkerGlobalScope(); |
139 | 239 |
140 ThreadIdentifier threadID = m_threadID; | |
141 | |
142 // The below assignment will destroy the context, which will in turn notify messaging proxy. | 240 // The below assignment will destroy the context, which will in turn notify messaging proxy. |
143 // We cannot let any objects survive past thread exit, because no other thre ad will run GC or otherwise destroy them. | 241 // We cannot let any objects survive past thread exit, because no other thre ad will run GC or otherwise destroy them. |
144 // If Oilpan is enabled, we detach of the context/global scope, with the fin al heap cleanup below sweeping it out. | 242 // If Oilpan is enabled, we detach of the context/global scope, with the fin al heap cleanup below sweeping it out. |
145 #if !ENABLE(OILPAN) | 243 #if !ENABLE(OILPAN) |
146 ASSERT(m_workerGlobalScope->hasOneRef()); | 244 ASSERT(m_workerGlobalScope->hasOneRef()); |
147 #endif | 245 #endif |
148 m_workerGlobalScope->dispose(); | 246 m_workerGlobalScope->dispose(); |
149 m_workerGlobalScope = nullptr; | 247 m_workerGlobalScope = nullptr; |
150 | 248 |
151 // Detach the ThreadState, cleaning out the thread's heap by | 249 // Detach the ThreadState, cleaning out the thread's heap by |
152 // performing a final GC. The cleanup operation will at the end | 250 // performing a final GC. The cleanup operation will at the end |
153 // assert that the heap is empty. If the heap does not become | 251 // assert that the heap is empty. If the heap does not become |
154 // empty, there are still pointers into the heap and those | 252 // empty, there are still pointers into the heap and those |
155 // pointers will be dangling after thread termination because we | 253 // pointers will be dangling after thread termination because we |
156 // are destroying the heap. It is important to detach while the | 254 // are destroying the heap. It is important to detach while the |
157 // thread is still valid. In particular, finalizers for objects in | 255 // thread is still valid. In particular, finalizers for objects in |
158 // the heap for this thread will need to access thread local data. | 256 // the heap for this thread will need to access thread local data. |
159 ThreadState::detach(); | 257 ThreadState::detach(); |
160 | 258 |
161 // Notify the proxy that the WorkerGlobalScope has been disposed of. | 259 // Notify the proxy that the WorkerGlobalScope has been disposed of. |
162 // This can free this thread object, hence it must not be touched afterwards . | 260 // This can free this thread object, hence it must not be touched afterwards . |
163 workerReportingProxy().workerGlobalScopeDestroyed(); | 261 workerReportingProxy().workerGlobalScopeDestroyed(); |
164 | 262 |
165 // Clean up PlatformThreadData before WTF::WTFThreadData goes away! | 263 // Clean up PlatformThreadData before WTF::WTFThreadData goes away! |
166 PlatformThreadData::current().destroy(); | 264 PlatformThreadData::current().destroy(); |
167 | 265 |
168 // The thread object may be already destroyed from notification now, don't t ry to access "this". | 266 // Set the timer function to null, which will cause the shared timer in |
169 detachThread(threadID); | 267 // WebThread to be deleted. It is important to do it here, since it |
170 } | 268 // should be deleted on the same thread that it executes on. |
171 | 269 m_sharedTimer->setFiredFunction(0); |
172 void WorkerThread::runEventLoop() | |
173 { | |
174 // Does not return until terminated. | |
175 m_runLoop.run(); | |
176 } | 270 } |
177 | 271 |
178 class WorkerThreadShutdownFinishTask : public ExecutionContextTask { | 272 class WorkerThreadShutdownFinishTask : public ExecutionContextTask { |
179 public: | 273 public: |
180 static PassOwnPtr<WorkerThreadShutdownFinishTask> create() | 274 static PassOwnPtr<WorkerThreadShutdownFinishTask> create() |
181 { | 275 { |
182 return adoptPtr(new WorkerThreadShutdownFinishTask()); | 276 return adoptPtr(new WorkerThreadShutdownFinishTask()); |
183 } | 277 } |
184 | 278 |
185 virtual void performTask(ExecutionContext *context) | 279 virtual void performTask(ExecutionContext *context) |
186 { | 280 { |
187 WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context); | 281 WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context); |
188 workerGlobalScope->clearInspector(); | 282 workerGlobalScope->clearInspector(); |
189 // It's not safe to call clearScript until all the cleanup tasks posted by functions initiated by WorkerThreadShutdownStartTask have completed. | 283 // It's not safe to call clearScript until all the cleanup tasks posted by functions initiated by WorkerThreadShutdownStartTask have completed. |
190 workerGlobalScope->clearScript(); | 284 workerGlobalScope->clearScript(); |
285 workerGlobalScope->thread()->webThread()->postTask(new Task(WTF::bind(&W orkerThread::cleanup, workerGlobalScope->thread()))); | |
191 } | 286 } |
192 | 287 |
193 virtual bool isCleanupTask() const { return true; } | 288 virtual bool isCleanupTask() const { return true; } |
194 }; | 289 }; |
195 | 290 |
196 class WorkerThreadShutdownStartTask : public ExecutionContextTask { | 291 class WorkerThreadShutdownStartTask : public ExecutionContextTask { |
197 public: | 292 public: |
198 static PassOwnPtr<WorkerThreadShutdownStartTask> create() | 293 static PassOwnPtr<WorkerThreadShutdownStartTask> create() |
199 { | 294 { |
200 return adoptPtr(new WorkerThreadShutdownStartTask()); | 295 return adoptPtr(new WorkerThreadShutdownStartTask()); |
(...skipping 15 matching lines...) Expand all Loading... | |
216 } | 311 } |
217 | 312 |
218 virtual bool isCleanupTask() const { return true; } | 313 virtual bool isCleanupTask() const { return true; } |
219 }; | 314 }; |
220 | 315 |
221 void WorkerThread::stop() | 316 void WorkerThread::stop() |
222 { | 317 { |
223 // Prevent the deadlock between GC and an attempt to stop a thread. | 318 // Prevent the deadlock between GC and an attempt to stop a thread. |
224 ThreadState::SafePointScope safePointScope(ThreadState::HeapPointersOnStack) ; | 319 ThreadState::SafePointScope safePointScope(ThreadState::HeapPointersOnStack) ; |
225 | 320 |
226 // Mutex protection is necessary because stop() can be called before the con text is fully created. | 321 // Protect against this method and initialize() racing each other. |
227 MutexLocker lock(m_threadCreationMutex); | 322 MutexLocker lock(m_threadCreationMutex); |
228 | 323 |
324 // If stop has already been called, just return. | |
325 if (m_terminated) | |
326 return; | |
327 | |
229 // Signal the thread to notify that the thread's stopping. | 328 // Signal the thread to notify that the thread's stopping. |
230 if (m_shutdownEvent) | 329 if (m_shutdownEvent) |
231 m_shutdownEvent->signal(); | 330 m_shutdownEvent->signal(); |
232 | 331 |
233 // Ensure that tasks are being handled by thread event loop. If script execu tion weren't forbidden, a while(1) loop in JS could keep the thread alive foreve r. | 332 // Ensure that tasks are being handled by thread event loop. If script execu tion weren't forbidden, a while(1) loop in JS could keep the thread alive foreve r. |
234 if (m_workerGlobalScope) { | 333 if (m_workerGlobalScope) { |
235 m_workerGlobalScope->script()->scheduleExecutionTermination(); | 334 m_workerGlobalScope->script()->scheduleExecutionTermination(); |
236 m_workerGlobalScope->wasRequestedToTerminate(); | 335 m_workerGlobalScope->wasRequestedToTerminate(); |
237 m_runLoop.postTaskAndTerminate(WorkerThreadShutdownStartTask::create()); | 336 InspectorInstrumentation::didKillAllExecutionContextTasks(m_workerGlobal Scope.get()); |
337 postTask(WorkerThreadShutdownStartTask::create()); | |
338 m_terminated = true; | |
238 return; | 339 return; |
239 } | 340 } |
240 m_runLoop.terminate(); | |
241 } | 341 } |
242 | 342 |
243 bool WorkerThread::isCurrentThread() const | 343 bool WorkerThread::isCurrentThread() const |
244 { | 344 { |
245 return m_threadID == currentThread(); | 345 return m_thread && m_thread->isCurrentThread(); |
346 } | |
347 | |
348 void WorkerThread::idleHandler() | |
349 { | |
350 if (m_terminated) | |
351 return; | |
352 | |
353 int64 delay = kLongIdleHandlerDelayMs; | |
354 | |
355 // Do a script engine idle notification if the next event is distant enough. | |
356 const double kMinIdleTimespan = 0.3; | |
357 if (!m_sharedTimer->nextFireTime() || m_sharedTimer->nextFireTime() > curren tTime() + kMinIdleTimespan) { | |
358 bool hasMoreWork = !m_workerGlobalScope->idleNotification(); | |
359 if (hasMoreWork) | |
360 delay = kShortIdleHandlerDelayMs; | |
361 } | |
362 | |
363 m_thread->postDelayedTask(new Task(WTF::bind(&WorkerThread::idleHandler, m_w eakFactory->createWeakPtr())), delay); | |
246 } | 364 } |
247 | 365 |
248 void WorkerThread::postTask(PassOwnPtr<ExecutionContextTask> task) | 366 void WorkerThread::postTask(PassOwnPtr<ExecutionContextTask> task) |
249 { | 367 { |
250 m_runLoop.postTask(task); | 368 m_thread->postTask(WorkerThreadTask::create(*this, task, true).leakPtr()); |
251 } | 369 } |
252 | 370 |
253 void WorkerThread::postDebuggerTask(PassOwnPtr<ExecutionContextTask> task) | 371 void WorkerThread::postDebuggerTask(PassOwnPtr<ExecutionContextTask> task) |
254 { | 372 { |
255 m_runLoop.postDebuggerTask(task); | 373 m_debuggerMessageQueue.append(WorkerThreadTask::create(*this, task, false)); |
374 postTask(RunDebuggerQueueTask::create(this)); | |
256 } | 375 } |
257 | 376 |
258 MessageQueueWaitResult WorkerThread::runDebuggerTask(WorkerRunLoop::WaitMode wai tMode) | 377 MessageQueueWaitResult WorkerThread::runDebuggerTask(WaitMode waitMode) |
259 { | 378 { |
260 return m_runLoop.runDebuggerTask(waitMode); | 379 ASSERT(isCurrentThread()); |
380 MessageQueueWaitResult result; | |
381 double absoluteTime = MessageQueue<blink::WebThread::Task>::infiniteTime(); | |
382 OwnPtr<blink::WebThread::Task> task; | |
383 { | |
384 if (waitMode == DontWaitForMessage) | |
385 absoluteTime = 0.0; | |
386 ThreadState::SafePointScope safePointScope(ThreadState::NoHeapPointersOn Stack); | |
387 task = m_debuggerMessageQueue.waitForMessageWithTimeout(result, absolute Time); | |
388 } | |
389 | |
390 if (result == MessageQueueMessageReceived) { | |
391 InspectorInstrumentation::willProcessTask(workerGlobalScope()); | |
392 task->run(); | |
393 InspectorInstrumentation::didProcessTask(workerGlobalScope()); | |
394 } | |
395 | |
396 return result; | |
397 } | |
398 | |
399 void WorkerThread::willEnterNestedLoop() | |
400 { | |
401 InspectorInstrumentation::willEnterNestedRunLoop(m_workerGlobalScope.get()); | |
402 } | |
403 | |
404 void WorkerThread::didLeaveNestedLoop() | |
405 { | |
406 InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get()); | |
261 } | 407 } |
262 | 408 |
263 } // namespace blink | 409 } // namespace blink |
OLD | NEW |