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 20 matching lines...) Expand all Loading... | |
| 31 #include "bindings/core/v8/ScriptSourceCode.h" | 31 #include "bindings/core/v8/ScriptSourceCode.h" |
| 32 #include "bindings/core/v8/V8GCController.h" | 32 #include "bindings/core/v8/V8GCController.h" |
| 33 #include "bindings/core/v8/V8Initializer.h" | 33 #include "bindings/core/v8/V8Initializer.h" |
| 34 #include "core/dom/Microtask.h" | 34 #include "core/dom/Microtask.h" |
| 35 #include "core/inspector/InspectorInstrumentation.h" | 35 #include "core/inspector/InspectorInstrumentation.h" |
| 36 #include "core/inspector/WorkerInspectorController.h" | 36 #include "core/inspector/WorkerInspectorController.h" |
| 37 #include "core/workers/DedicatedWorkerGlobalScope.h" | 37 #include "core/workers/DedicatedWorkerGlobalScope.h" |
| 38 #include "core/workers/WorkerClients.h" | 38 #include "core/workers/WorkerClients.h" |
| 39 #include "core/workers/WorkerReportingProxy.h" | 39 #include "core/workers/WorkerReportingProxy.h" |
| 40 #include "core/workers/WorkerThreadStartupData.h" | 40 #include "core/workers/WorkerThreadStartupData.h" |
| 41 #include "platform/PlatformThreadData.h" | |
| 42 #include "platform/Task.h" | 41 #include "platform/Task.h" |
| 43 #include "platform/ThreadTimers.h" | |
| 44 #include "platform/heap/SafePoint.h" | 42 #include "platform/heap/SafePoint.h" |
| 45 #include "platform/heap/ThreadState.h" | 43 #include "platform/heap/ThreadState.h" |
| 46 #include "platform/weborigin/KURL.h" | 44 #include "platform/weborigin/KURL.h" |
| 47 #include "public/platform/Platform.h" | 45 #include "public/platform/Platform.h" |
| 48 #include "public/platform/WebThread.h" | 46 #include "public/platform/WebThread.h" |
| 49 #include "public/platform/WebWaitableEvent.h" | 47 #include "public/platform/WebWaitableEvent.h" |
| 50 #include "wtf/Noncopyable.h" | 48 #include "wtf/Noncopyable.h" |
| 51 #include "wtf/WeakPtr.h" | 49 #include "wtf/WeakPtr.h" |
| 52 #include "wtf/text/WTFString.h" | 50 #include "wtf/text/WTFString.h" |
| 53 | 51 |
| 54 #include <utility> | 52 #include <utility> |
| 55 | 53 |
| 56 namespace blink { | 54 namespace blink { |
| 57 | 55 |
| 58 namespace { | 56 namespace { |
| 59 const int64_t kShortIdleHandlerDelayMs = 1000; | |
| 60 const int64_t kLongIdleHandlerDelayMs = 10*1000; | |
| 61 | 57 |
| 62 class MicrotaskRunner : public WebThread::TaskObserver { | 58 class MicrotaskRunner : public WebThread::TaskObserver { |
| 63 public: | 59 public: |
| 64 explicit MicrotaskRunner(WorkerThread* workerThread) | 60 explicit MicrotaskRunner(WorkerThread* workerThread) |
| 65 : m_workerThread(workerThread) | 61 : m_workerThread(workerThread) |
| 66 { | 62 { |
| 67 } | 63 } |
| 68 | 64 |
| 69 virtual void willProcessTask() override { } | 65 virtual void willProcessTask() override { } |
| 70 virtual void didProcessTask() override | 66 virtual void didProcessTask() override |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 126 : m_closure(closure) | 122 : m_closure(closure) |
| 127 , m_weakFactory(this) | 123 , m_weakFactory(this) |
| 128 , m_taskCanceled(false) | 124 , m_taskCanceled(false) |
| 129 { } | 125 { } |
| 130 | 126 |
| 131 OwnPtr<Closure> m_closure; | 127 OwnPtr<Closure> m_closure; |
| 132 WeakPtrFactory<WorkerThreadCancelableTask> m_weakFactory; | 128 WeakPtrFactory<WorkerThreadCancelableTask> m_weakFactory; |
| 133 bool m_taskCanceled; | 129 bool m_taskCanceled; |
| 134 }; | 130 }; |
| 135 | 131 |
| 136 class WorkerSharedTimer : public SharedTimer { | |
| 137 public: | |
| 138 explicit WorkerSharedTimer(WorkerThread* workerThread) | |
| 139 : m_workerThread(workerThread) | |
| 140 , m_running(false) | |
| 141 { } | |
| 142 | |
| 143 typedef void (*SharedTimerFunction)(); | |
| 144 virtual void setFiredFunction(SharedTimerFunction func) | |
| 145 { | |
| 146 m_sharedTimerFunction = func; | |
| 147 } | |
| 148 | |
| 149 virtual void setFireInterval(double interval) | |
| 150 { | |
| 151 ASSERT(m_sharedTimerFunction); | |
| 152 | |
| 153 // See BlinkPlatformImpl::setSharedTimerFireInterval for explanation of | |
| 154 // why ceil is used in the interval calculation. | |
| 155 int64_t delay = static_cast<int64_t>(ceil(interval * 1000)); | |
| 156 | |
| 157 if (delay < 0) { | |
| 158 delay = 0; | |
| 159 } | |
| 160 | |
| 161 m_running = true; | |
| 162 | |
| 163 if (m_lastQueuedTask.get()) | |
| 164 m_lastQueuedTask->cancelTask(); | |
| 165 | |
| 166 // Now queue the task as a cancellable one. | |
| 167 OwnPtr<WorkerThreadCancelableTask> task = WorkerThreadCancelableTask::cr eate(bind(&WorkerSharedTimer::OnTimeout, this)); | |
| 168 m_lastQueuedTask = task->createWeakPtr(); | |
| 169 m_workerThread->postDelayedTask(FROM_HERE, task.release(), delay); | |
| 170 } | |
| 171 | |
| 172 virtual void stop() | |
| 173 { | |
| 174 m_running = false; | |
| 175 m_lastQueuedTask = nullptr; | |
| 176 } | |
| 177 | |
| 178 private: | |
| 179 void OnTimeout() | |
| 180 { | |
| 181 ASSERT(m_workerThread->workerGlobalScope()); | |
| 182 | |
| 183 m_lastQueuedTask = nullptr; | |
| 184 | |
| 185 if (m_sharedTimerFunction && m_running && !m_workerThread->workerGlobalS cope()->isClosing()) | |
| 186 m_sharedTimerFunction(); | |
| 187 } | |
| 188 | |
| 189 WorkerThread* m_workerThread; | |
| 190 SharedTimerFunction m_sharedTimerFunction; | |
| 191 bool m_running; | |
| 192 | |
| 193 // The task to run OnTimeout, if any. While OnTimeout resets | |
| 194 // m_lastQueuedTask, this must be a weak pointer because the | |
| 195 // worker runloop may delete the task as it is shutting down. | |
| 196 WeakPtr<WorkerThreadCancelableTask> m_lastQueuedTask; | |
| 197 }; | |
| 198 | |
| 199 class WorkerThreadTask : public blink::WebThread::Task { | 132 class WorkerThreadTask : public blink::WebThread::Task { |
| 200 WTF_MAKE_NONCOPYABLE(WorkerThreadTask); WTF_MAKE_FAST_ALLOCATED(WorkerThread Task); | 133 WTF_MAKE_NONCOPYABLE(WorkerThreadTask); WTF_MAKE_FAST_ALLOCATED(WorkerThread Task); |
| 201 public: | 134 public: |
| 202 static PassOwnPtr<WorkerThreadTask> create(WorkerThread& workerThread, PassO wnPtr<ExecutionContextTask> task, bool isInstrumented) | 135 static PassOwnPtr<WorkerThreadTask> create(WorkerThread& workerThread, PassO wnPtr<ExecutionContextTask> task, bool isInstrumented) |
| 203 { | 136 { |
| 204 return adoptPtr(new WorkerThreadTask(workerThread, task, isInstrumented) ); | 137 return adoptPtr(new WorkerThreadTask(workerThread, task, isInstrumented) ); |
| 205 } | 138 } |
| 206 | 139 |
| 207 virtual ~WorkerThreadTask() { } | 140 virtual ~WorkerThreadTask() { } |
| 208 | 141 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 258 }; | 191 }; |
| 259 | 192 |
| 260 WorkerThread::WorkerThread(PassRefPtr<WorkerLoaderProxy> workerLoaderProxy, Work erReportingProxy& workerReportingProxy, PassOwnPtrWillBeRawPtr<WorkerThreadStart upData> startupData) | 193 WorkerThread::WorkerThread(PassRefPtr<WorkerLoaderProxy> workerLoaderProxy, Work erReportingProxy& workerReportingProxy, PassOwnPtrWillBeRawPtr<WorkerThreadStart upData> startupData) |
| 261 : m_terminated(false) | 194 : m_terminated(false) |
| 262 , m_workerLoaderProxy(workerLoaderProxy) | 195 , m_workerLoaderProxy(workerLoaderProxy) |
| 263 , m_workerReportingProxy(workerReportingProxy) | 196 , m_workerReportingProxy(workerReportingProxy) |
| 264 , m_startupData(startupData) | 197 , m_startupData(startupData) |
| 265 , m_isolate(nullptr) | 198 , m_isolate(nullptr) |
| 266 , m_shutdownEvent(adoptPtr(blink::Platform::current()->createWaitableEvent() )) | 199 , m_shutdownEvent(adoptPtr(blink::Platform::current()->createWaitableEvent() )) |
| 267 , m_terminationEvent(adoptPtr(blink::Platform::current()->createWaitableEven t())) | 200 , m_terminationEvent(adoptPtr(blink::Platform::current()->createWaitableEven t())) |
| 201 , m_dontStartIdleTaskYet(false) | |
| 268 { | 202 { |
| 269 MutexLocker lock(threadSetMutex()); | 203 MutexLocker lock(threadSetMutex()); |
| 270 workerThreads().add(this); | 204 workerThreads().add(this); |
| 271 } | 205 } |
| 272 | 206 |
| 273 WorkerThread::~WorkerThread() | 207 WorkerThread::~WorkerThread() |
| 274 { | 208 { |
| 275 MutexLocker lock(threadSetMutex()); | 209 MutexLocker lock(threadSetMutex()); |
| 276 ASSERT(workerThreads().contains(this)); | 210 ASSERT(workerThreads().contains(this)); |
| 277 workerThreads().remove(this); | 211 workerThreads().remove(this); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 293 m_workerInspectorController->interruptAndDispatchInspectorCommands(); | 227 m_workerInspectorController->interruptAndDispatchInspectorCommands(); |
| 294 } | 228 } |
| 295 | 229 |
| 296 PlatformThreadId WorkerThread::platformThreadId() const | 230 PlatformThreadId WorkerThread::platformThreadId() const |
| 297 { | 231 { |
| 298 if (!m_thread) | 232 if (!m_thread) |
| 299 return 0; | 233 return 0; |
| 300 return m_thread->platformThread().threadId(); | 234 return m_thread->platformThread().threadId(); |
| 301 } | 235 } |
| 302 | 236 |
| 237 class WorkerThreadWaitUntilIdleTask : public WebThread::Task, public WebThread:: IdleTask { | |
|
Sami
2015/04/02 10:59:19
Maybe "wait until quiescence" would be a better te
alex clarke (OOO till 29th)
2015/04/08 15:43:35
Done.
| |
| 238 public: | |
| 239 explicit WorkerThreadWaitUntilIdleTask(WorkerThread* thread) : m_thread(thre ad) { } | |
| 240 | |
| 241 ~WorkerThreadWaitUntilIdleTask() override | |
| 242 { | |
| 243 } | |
| 244 | |
| 245 void run() override | |
| 246 { | |
| 247 m_thread->maybeStartIdleTask(); | |
| 248 } | |
| 249 | |
| 250 void run(double) override | |
| 251 { | |
| 252 m_thread->dontStartIdleTaskYet(); | |
| 253 } | |
| 254 | |
| 255 private: | |
| 256 RawPtr<WorkerThread> m_thread; | |
| 257 }; | |
| 258 | |
| 259 class WorkerThreadIdleTask : public WebThread::IdleTask { | |
| 260 public: | |
| 261 explicit WorkerThreadIdleTask(WorkerThread* thread) | |
| 262 : m_thread(thread) { } | |
| 263 | |
| 264 ~WorkerThreadIdleTask() override { } | |
| 265 | |
| 266 void run(double deadlineSeconds) override | |
| 267 { | |
| 268 m_thread->idleTask(deadlineSeconds); | |
| 269 } | |
| 270 | |
| 271 private: | |
| 272 RawPtr<WorkerThread> m_thread; | |
| 273 }; | |
| 274 | |
| 275 class WorkerThreadWakeupIdleTask : public WebThread::IdleTask { | |
| 276 public: | |
| 277 explicit WorkerThreadWakeupIdleTask(WorkerThread* thread) | |
| 278 : m_thread(thread) { } | |
| 279 | |
| 280 ~WorkerThreadWakeupIdleTask() override { } | |
| 281 | |
| 282 void run(double) override | |
| 283 { | |
| 284 m_thread->dontStartIdleTaskYet(); | |
| 285 m_thread->maybeStartIdleTask(); | |
| 286 } | |
| 287 | |
| 288 private: | |
| 289 RawPtr<WorkerThread> m_thread; | |
| 290 }; | |
| 291 | |
| 303 void WorkerThread::initialize() | 292 void WorkerThread::initialize() |
| 304 { | 293 { |
| 305 KURL scriptURL = m_startupData->m_scriptURL; | 294 KURL scriptURL = m_startupData->m_scriptURL; |
| 306 String sourceCode = m_startupData->m_sourceCode; | 295 String sourceCode = m_startupData->m_sourceCode; |
| 307 WorkerThreadStartMode startMode = m_startupData->m_startMode; | 296 WorkerThreadStartMode startMode = m_startupData->m_startMode; |
| 308 OwnPtr<Vector<char>> cachedMetaData = m_startupData->m_cachedMetaData.releas e(); | 297 OwnPtr<Vector<char>> cachedMetaData = m_startupData->m_cachedMetaData.releas e(); |
| 309 V8CacheOptions v8CacheOptions = m_startupData->m_v8CacheOptions; | 298 V8CacheOptions v8CacheOptions = m_startupData->m_v8CacheOptions; |
| 310 | 299 |
| 311 { | 300 { |
| 312 MutexLocker lock(m_threadCreationMutex); | 301 MutexLocker lock(m_threadCreationMutex); |
| 313 | 302 |
| 314 // The worker was terminated before the thread had a chance to run. | 303 // The worker was terminated before the thread had a chance to run. |
| 315 if (m_terminated) { | 304 if (m_terminated) { |
| 316 // Notify the proxy that the WorkerGlobalScope has been disposed of. | 305 // Notify the proxy that the WorkerGlobalScope has been disposed of. |
| 317 // This can free this thread object, hence it must not be touched af terwards. | 306 // This can free this thread object, hence it must not be touched af terwards. |
| 318 m_workerReportingProxy.workerThreadTerminated(); | 307 m_workerReportingProxy.workerThreadTerminated(); |
| 319 return; | 308 return; |
| 320 } | 309 } |
| 321 | 310 |
| 322 m_microtaskRunner = adoptPtr(new MicrotaskRunner(this)); | 311 m_microtaskRunner = adoptPtr(new MicrotaskRunner(this)); |
| 323 m_thread->addTaskObserver(m_microtaskRunner.get()); | 312 m_thread->addTaskObserver(m_microtaskRunner.get()); |
| 324 m_thread->attachGC(); | 313 m_thread->attachGC(); |
| 325 | 314 |
| 326 m_isolate = initializeIsolate(); | 315 m_isolate = initializeIsolate(); |
| 327 m_workerGlobalScope = createWorkerGlobalScope(m_startupData.release()); | 316 m_workerGlobalScope = createWorkerGlobalScope(m_startupData.release()); |
| 328 | |
| 329 PlatformThreadData::current().threadTimers().setSharedTimer(adoptPtr(new WorkerSharedTimer(this))); | |
| 330 } | 317 } |
| 331 | 318 |
| 332 // The corresponding call to stopRunLoop() is in ~WorkerScriptController(). | 319 // The corresponding call to stopRunLoop() is in ~WorkerScriptController(). |
| 333 didStartRunLoop(); | 320 didStartRunLoop(); |
| 334 | 321 |
| 335 // Notify proxy that a new WorkerGlobalScope has been created and started. | 322 // Notify proxy that a new WorkerGlobalScope has been created and started. |
| 336 m_workerReportingProxy.workerGlobalScopeStarted(m_workerGlobalScope.get()); | 323 m_workerReportingProxy.workerGlobalScopeStarted(m_workerGlobalScope.get()); |
| 337 | 324 |
| 338 WorkerScriptController* script = m_workerGlobalScope->script(); | 325 WorkerScriptController* script = m_workerGlobalScope->script(); |
| 339 if (!script->isExecutionForbidden()) | 326 if (!script->isExecutionForbidden()) |
| 340 script->initializeContextIfNeeded(); | 327 script->initializeContextIfNeeded(); |
| 341 if (startMode == PauseWorkerGlobalScopeOnStart) | 328 if (startMode == PauseWorkerGlobalScopeOnStart) |
| 342 m_workerGlobalScope->workerInspectorController()->pauseOnStart(); | 329 m_workerGlobalScope->workerInspectorController()->pauseOnStart(); |
| 343 | 330 |
| 344 OwnPtr<CachedMetadataHandler> handler(workerGlobalScope()->createWorkerScrip tCachedMetadataHandler(scriptURL, cachedMetaData.get())); | 331 OwnPtr<CachedMetadataHandler> handler(workerGlobalScope()->createWorkerScrip tCachedMetadataHandler(scriptURL, cachedMetaData.get())); |
| 345 bool success = script->evaluate(ScriptSourceCode(sourceCode, scriptURL), nul lptr, handler.get(), v8CacheOptions); | 332 bool success = script->evaluate(ScriptSourceCode(sourceCode, scriptURL), nul lptr, handler.get(), v8CacheOptions); |
| 346 m_workerGlobalScope->didEvaluateWorkerScript(); | 333 m_workerGlobalScope->didEvaluateWorkerScript(); |
| 347 m_workerReportingProxy.didEvaluateWorkerScript(success); | 334 m_workerReportingProxy.didEvaluateWorkerScript(success); |
| 348 | 335 |
| 349 postInitialize(); | 336 postInitialize(); |
| 350 | 337 |
| 351 postDelayedTask(FROM_HERE, createSameThreadTask(&WorkerThread::idleHandler, this), kShortIdleHandlerDelayMs); | 338 dontStartIdleTaskYet(); |
|
Sami
2015/04/02 10:59:19
endIdlePeriod() to match the chromium side terms?
alex clarke (OOO till 29th)
2015/04/08 15:43:35
I'm not really convinced those terms are helpful i
| |
| 339 maybeStartIdleTask(); | |
| 352 } | 340 } |
| 353 | 341 |
| 354 PassOwnPtr<WebThreadSupportingGC> WorkerThread::createWebThreadSupportingGC() | 342 PassOwnPtr<WebThreadSupportingGC> WorkerThread::createWebThreadSupportingGC() |
| 355 { | 343 { |
| 356 return WebThreadSupportingGC::create("WebCore: Worker"); | 344 return WebThreadSupportingGC::create("WebCore: Worker"); |
| 357 } | 345 } |
| 358 | 346 |
| 359 void WorkerThread::cleanup() | 347 void WorkerThread::cleanup() |
| 360 { | 348 { |
| 361 // This should be called before we start the shutdown procedure. | 349 // This should be called before we start the shutdown procedure. |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 374 destroyIsolate(); | 362 destroyIsolate(); |
| 375 | 363 |
| 376 m_thread->removeTaskObserver(m_microtaskRunner.get()); | 364 m_thread->removeTaskObserver(m_microtaskRunner.get()); |
| 377 m_microtaskRunner = nullptr; | 365 m_microtaskRunner = nullptr; |
| 378 | 366 |
| 379 // Notify the proxy that the WorkerGlobalScope has been disposed of. | 367 // Notify the proxy that the WorkerGlobalScope has been disposed of. |
| 380 // This can free this thread object, hence it must not be touched afterwards . | 368 // This can free this thread object, hence it must not be touched afterwards . |
| 381 workerReportingProxy().workerThreadTerminated(); | 369 workerReportingProxy().workerThreadTerminated(); |
| 382 | 370 |
| 383 m_terminationEvent->signal(); | 371 m_terminationEvent->signal(); |
| 384 | |
| 385 // Clean up PlatformThreadData before WTF::WTFThreadData goes away! | |
| 386 PlatformThreadData::current().destroy(); | |
| 387 } | 372 } |
| 388 | 373 |
| 389 class WorkerThreadShutdownFinishTask : public ExecutionContextTask { | 374 class WorkerThreadShutdownFinishTask : public ExecutionContextTask { |
| 390 public: | 375 public: |
| 391 static PassOwnPtr<WorkerThreadShutdownFinishTask> create() | 376 static PassOwnPtr<WorkerThreadShutdownFinishTask> create() |
| 392 { | 377 { |
| 393 return adoptPtr(new WorkerThreadShutdownFinishTask()); | 378 return adoptPtr(new WorkerThreadShutdownFinishTask()); |
| 394 } | 379 } |
| 395 | 380 |
| 396 virtual void performTask(ExecutionContext *context) | 381 virtual void performTask(ExecutionContext *context) |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 411 public: | 396 public: |
| 412 static PassOwnPtr<WorkerThreadShutdownStartTask> create() | 397 static PassOwnPtr<WorkerThreadShutdownStartTask> create() |
| 413 { | 398 { |
| 414 return adoptPtr(new WorkerThreadShutdownStartTask()); | 399 return adoptPtr(new WorkerThreadShutdownStartTask()); |
| 415 } | 400 } |
| 416 | 401 |
| 417 virtual void performTask(ExecutionContext *context) | 402 virtual void performTask(ExecutionContext *context) |
| 418 { | 403 { |
| 419 WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context); | 404 WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context); |
| 420 workerGlobalScope->stopActiveDOMObjects(); | 405 workerGlobalScope->stopActiveDOMObjects(); |
| 421 PlatformThreadData::current().threadTimers().setSharedTimer(nullptr); | |
| 422 | 406 |
| 423 // Event listeners would keep DOMWrapperWorld objects alive for too long . Also, they have references to JS objects, | 407 // Event listeners would keep DOMWrapperWorld objects alive for too long . Also, they have references to JS objects, |
| 424 // which become dangling once Heap is destroyed. | 408 // which become dangling once Heap is destroyed. |
| 425 workerGlobalScope->removeAllEventListeners(); | 409 workerGlobalScope->removeAllEventListeners(); |
| 426 | 410 |
| 427 // Stick a shutdown command at the end of the queue, so that we deal | 411 // Stick a shutdown command at the end of the queue, so that we deal |
| 428 // with all the cleanup tasks the databases post first. | 412 // with all the cleanup tasks the databases post first. |
| 429 workerGlobalScope->postTask(FROM_HERE, WorkerThreadShutdownFinishTask::c reate()); | 413 workerGlobalScope->postTask(FROM_HERE, WorkerThreadShutdownFinishTask::c reate()); |
| 430 } | 414 } |
| 431 | 415 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 503 | 487 |
| 504 for (WorkerThread* thread : threads) | 488 for (WorkerThread* thread : threads) |
| 505 thread->terminationEvent()->wait(); | 489 thread->terminationEvent()->wait(); |
| 506 } | 490 } |
| 507 | 491 |
| 508 bool WorkerThread::isCurrentThread() const | 492 bool WorkerThread::isCurrentThread() const |
| 509 { | 493 { |
| 510 return m_thread && m_thread->isCurrentThread(); | 494 return m_thread && m_thread->isCurrentThread(); |
| 511 } | 495 } |
| 512 | 496 |
| 513 void WorkerThread::idleHandler() | 497 void WorkerThread::dontStartIdleTaskYet() |
| 498 { | |
| 499 m_dontStartIdleTaskYet = true; | |
| 500 } | |
| 501 | |
| 502 void WorkerThread::maybeStartIdleTask() | |
| 503 { | |
| 504 if (m_dontStartIdleTaskYet) { | |
| 505 // We don't want to be too quick to enter idle mode (where we start doin g more GC) because | |
| 506 // that might cause the worker thread to be unresponsive to messages. T o avoid this we | |
| 507 // check every 300ms if any tasks have been run. If they havent we can start doing idle GCs. | |
| 508 // NOTE we use the IdleTaskAfterWakeup call to work out if something has run. It's execution | |
| 509 // only happens if some other task gets posted. | |
| 510 m_thread->postDelayedTask(FROM_HERE, new WorkerThreadWaitUntilIdleTask(t his), 300ul); | |
| 511 m_thread->postIdleTaskAfterWakeup(FROM_HERE, new WorkerThreadWaitUntilId leTask(this)); | |
| 512 m_dontStartIdleTaskYet = false; | |
| 513 return; | |
| 514 } | |
| 515 | |
| 516 m_thread->postIdleTask(FROM_HERE, new WorkerThreadIdleTask(this)); | |
| 517 } | |
| 518 | |
| 519 void WorkerThread::idleTask(double deadlineSeconds) | |
| 514 { | 520 { |
| 515 ASSERT(m_workerGlobalScope.get()); | 521 ASSERT(m_workerGlobalScope.get()); |
| 516 int64_t delay = kLongIdleHandlerDelayMs; | 522 bool gcFinished = false; |
| 523 if (deadlineSeconds > Platform::current()->monotonicallyIncreasingTime()) | |
| 524 gcFinished = isolate()->IdleNotificationDeadline(deadlineSeconds); | |
| 517 | 525 |
| 518 // Do a script engine idle notification if the next event is distant enough. | 526 if (gcFinished) |
| 519 const double kMinIdleTimespan = 0.3; | 527 m_thread->postIdleTaskAfterWakeup(FROM_HERE, new WorkerThreadWakeupIdleT ask(this)); |
| 520 const double nextFireTime = PlatformThreadData::current().threadTimers().nex tFireTime(); | 528 else |
| 521 if (nextFireTime == 0.0 || nextFireTime > currentTime() + kMinIdleTimespan) { | 529 m_thread->postIdleTask(FROM_HERE, new WorkerThreadIdleTask(this)); |
| 522 bool hasMoreWork = !isolate()->IdleNotificationDeadline(Platform::curren t()->monotonicallyIncreasingTime() + 1.0); | |
| 523 if (hasMoreWork) | |
| 524 delay = kShortIdleHandlerDelayMs; | |
| 525 } | |
| 526 | |
| 527 postDelayedTask(FROM_HERE, createSameThreadTask(&WorkerThread::idleHandler, this), delay); | |
| 528 } | 530 } |
| 529 | 531 |
| 530 void WorkerThread::postTask(const WebTraceLocation& location, PassOwnPtr<Executi onContextTask> task) | 532 void WorkerThread::postTask(const WebTraceLocation& location, PassOwnPtr<Executi onContextTask> task) |
| 531 { | 533 { |
| 532 m_thread->postTask(location, WorkerThreadTask::create(*this, task, true).lea kPtr()); | 534 m_thread->postTask(location, WorkerThreadTask::create(*this, task, true).lea kPtr()); |
| 533 } | 535 } |
| 534 | 536 |
| 535 void WorkerThread::postDelayedTask(const WebTraceLocation& location, PassOwnPtr< ExecutionContextTask> task, long long delayMs) | 537 void WorkerThread::postDelayedTask(const WebTraceLocation& location, PassOwnPtr< ExecutionContextTask> task, long long delayMs) |
| 536 { | 538 { |
| 537 m_thread->postDelayedTask(location, WorkerThreadTask::create(*this, task, tr ue).leakPtr(), delayMs); | 539 m_thread->postDelayedTask(location, WorkerThreadTask::create(*this, task, tr ue).leakPtr(), delayMs); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 611 InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get()); | 613 InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get()); |
| 612 } | 614 } |
| 613 | 615 |
| 614 void WorkerThread::setWorkerInspectorController(WorkerInspectorController* worke rInspectorController) | 616 void WorkerThread::setWorkerInspectorController(WorkerInspectorController* worke rInspectorController) |
| 615 { | 617 { |
| 616 MutexLocker locker(m_workerInspectorControllerMutex); | 618 MutexLocker locker(m_workerInspectorControllerMutex); |
| 617 m_workerInspectorController = workerInspectorController; | 619 m_workerInspectorController = workerInspectorController; |
| 618 } | 620 } |
| 619 | 621 |
| 620 } // namespace blink | 622 } // namespace blink |
| OLD | NEW |