| 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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 DEFINE_STATIC_LOCAL(HashSet<WorkerThread*>, threads, ()); | 78 DEFINE_STATIC_LOCAL(HashSet<WorkerThread*>, threads, ()); |
| 79 return threads; | 79 return threads; |
| 80 } | 80 } |
| 81 | 81 |
| 82 unsigned WorkerThread::workerThreadCount() | 82 unsigned WorkerThread::workerThreadCount() |
| 83 { | 83 { |
| 84 MutexLocker lock(threadSetMutex()); | 84 MutexLocker lock(threadSetMutex()); |
| 85 return workerThreads().size(); | 85 return workerThreads().size(); |
| 86 } | 86 } |
| 87 | 87 |
| 88 class WorkerThreadTask : public blink::WebThread::Task { |
| 89 WTF_MAKE_NONCOPYABLE(WorkerThreadTask); WTF_MAKE_FAST_ALLOCATED; |
| 90 public: |
| 91 static PassOwnPtr<WorkerThreadTask> create(const WorkerThread& workerThread,
PassOwnPtr<ExecutionContextTask> task, bool isInstrumented) |
| 92 { |
| 93 return adoptPtr(new WorkerThreadTask(workerThread, task, isInstrumented)
); |
| 94 } |
| 95 |
| 96 virtual ~WorkerThreadTask() { } |
| 97 |
| 98 virtual void run() OVERRIDE |
| 99 { |
| 100 WorkerGlobalScope* workerGlobalScope = m_workerThread.workerGlobalScope(
); |
| 101 // Tasks could be put on the message loop after the cleanup task, |
| 102 // ensure none of those are ran. |
| 103 if (!workerGlobalScope) |
| 104 return; |
| 105 |
| 106 if (m_isInstrumented) |
| 107 InspectorInstrumentation::willPerformExecutionContextTask(workerGlob
alScope, m_task.get()); |
| 108 if ((!workerGlobalScope->isClosing() && !m_workerThread.terminated()) ||
m_task->isCleanupTask()) |
| 109 m_task->performTask(workerGlobalScope); |
| 110 if (m_isInstrumented) |
| 111 InspectorInstrumentation::didPerformExecutionContextTask(workerGloba
lScope); |
| 112 } |
| 113 |
| 114 base::WeakPtrFactory<blink::WebThread::Task>& weakPtrFactory() |
| 115 { |
| 116 return m_weakFactory; |
| 117 } |
| 118 |
| 119 private: |
| 120 WorkerThreadTask(const WorkerThread& workerThread, PassOwnPtr<ExecutionConte
xtTask> task, bool isInstrumented) |
| 121 : m_workerThread(workerThread) |
| 122 , m_task(task) |
| 123 , m_isInstrumented(isInstrumented) |
| 124 , m_weakFactory(this) |
| 125 { |
| 126 if (m_isInstrumented) |
| 127 m_isInstrumented = !m_task->taskNameForInstrumentation().isEmpty(); |
| 128 if (m_isInstrumented) |
| 129 InspectorInstrumentation::didPostExecutionContextTask(m_workerThread
.workerGlobalScope(), m_task.get()); |
| 130 } |
| 131 |
| 132 const WorkerThread& m_workerThread; |
| 133 OwnPtr<ExecutionContextTask> m_task; |
| 134 bool m_isInstrumented; |
| 135 base::WeakPtrFactory<blink::WebThread::Task> m_weakFactory; |
| 136 }; |
| 137 |
| 88 class WorkerSharedTimer : public SharedTimer { | 138 class WorkerSharedTimer : public SharedTimer { |
| 89 public: | 139 public: |
| 90 explicit WorkerSharedTimer(WorkerThread* workerThread) | 140 explicit WorkerSharedTimer(WorkerThread* workerThread) |
| 91 : m_workerThread(workerThread) | 141 : m_workerThread(workerThread) |
| 92 , m_nextFireTime(0.0) | 142 , m_nextFireTime(0.0) |
| 93 , m_running(false) | 143 , m_running(false) |
| 94 { } | 144 { } |
| 95 | 145 |
| 96 typedef void (*SharedTimerFunction)(); | 146 typedef void (*SharedTimerFunction)(); |
| 97 virtual void setFiredFunction(SharedTimerFunction func) | 147 virtual void setFiredFunction(SharedTimerFunction func) |
| (...skipping 11 matching lines...) Expand all Loading... |
| 109 // why ceil is used in the interval calculation. | 159 // why ceil is used in the interval calculation. |
| 110 int64 delay = static_cast<int64>(ceil(interval * 1000)); | 160 int64 delay = static_cast<int64>(ceil(interval * 1000)); |
| 111 | 161 |
| 112 if (delay < 0) { | 162 if (delay < 0) { |
| 113 delay = 0; | 163 delay = 0; |
| 114 m_nextFireTime = 0.0; | 164 m_nextFireTime = 0.0; |
| 115 } | 165 } |
| 116 | 166 |
| 117 m_running = true; | 167 m_running = true; |
| 118 m_nextFireTime = currentTime() + interval; | 168 m_nextFireTime = currentTime() + interval; |
| 119 m_workerThread->postDelayedTask(createSameThreadTask(&WorkerSharedTimer:
:OnTimeout, this), delay); | 169 if (m_lastQueuedTask) { |
| 170 // If something was queued up before this, check if its later than t
he current timer |
| 171 if (interval < m_lastQueuedTaskTimer->nextFireInterval()) { |
| 172 m_lastQueuedTask->weakPtrFactory().InvalidateWeakPtrs(); |
| 173 m_lastQueuedTask = 0; |
| 174 m_lastQueuedTaskTimer = 0; |
| 175 } |
| 176 } |
| 177 if (!m_lastQueuedTask) { |
| 178 // Now queue the task as a cancellable one. |
| 179 WorkerThreadTask* nextDelayedTask = WorkerThreadTask::create(*m_work
erThread |
| 180 , createSameThreadTask(&WorkerSharedTimer::OnTimeout, this), tru
e).leakPtr(); |
| 181 m_workerThread->postCancellableDelayedTask(nextDelayedTask, delay); |
| 182 // The current timer should ideally be at the top of the heap as its
assumed to be the smallest interval in the heap |
| 183 m_lastQueuedTask = nextDelayedTask; |
| 184 m_lastQueuedTaskTimer = PlatformThreadData::current().threadTimers()
.timerHeap().first(); |
| 185 } |
| 120 } | 186 } |
| 121 | 187 |
| 122 virtual void stop() | 188 virtual void stop() |
| 123 { | 189 { |
| 124 m_running = false; | 190 m_running = false; |
| 125 } | 191 } |
| 126 | 192 |
| 127 double nextFireTime() { return m_nextFireTime; } | 193 double nextFireTime() { return m_nextFireTime; } |
| 128 | 194 |
| 129 private: | 195 private: |
| 130 void OnTimeout() | 196 void OnTimeout() |
| 131 { | 197 { |
| 132 ASSERT(m_workerThread->workerGlobalScope()); | 198 ASSERT(m_workerThread->workerGlobalScope()); |
| 199 |
| 200 m_lastQueuedTask = 0; |
| 201 m_lastQueuedTaskTimer = 0; |
| 202 |
| 133 if (m_sharedTimerFunction && m_running && !m_workerThread->workerGlobalS
cope()->isClosing()) | 203 if (m_sharedTimerFunction && m_running && !m_workerThread->workerGlobalS
cope()->isClosing()) |
| 134 m_sharedTimerFunction(); | 204 m_sharedTimerFunction(); |
| 135 } | 205 } |
| 136 | 206 |
| 137 WorkerThread* m_workerThread; | 207 WorkerThread* m_workerThread; |
| 138 SharedTimerFunction m_sharedTimerFunction; | 208 SharedTimerFunction m_sharedTimerFunction; |
| 139 double m_nextFireTime; | 209 double m_nextFireTime; |
| 140 bool m_running; | 210 bool m_running; |
| 211 static WorkerThreadTask* m_lastQueuedTask; |
| 212 static TimerBase* m_lastQueuedTaskTimer; |
| 141 }; | 213 }; |
| 142 | 214 |
| 143 class WorkerThreadTask : public blink::WebThread::Task { | 215 WorkerThreadTask* WorkerSharedTimer::m_lastQueuedTask = 0; |
| 144 WTF_MAKE_NONCOPYABLE(WorkerThreadTask); WTF_MAKE_FAST_ALLOCATED; | 216 TimerBase* WorkerSharedTimer::m_lastQueuedTaskTimer = 0; |
| 145 public: | |
| 146 static PassOwnPtr<WorkerThreadTask> create(const WorkerThread& workerThread,
PassOwnPtr<ExecutionContextTask> task, bool isInstrumented) | |
| 147 { | |
| 148 return adoptPtr(new WorkerThreadTask(workerThread, task, isInstrumented)
); | |
| 149 } | |
| 150 | |
| 151 virtual ~WorkerThreadTask() { } | |
| 152 | |
| 153 virtual void run() OVERRIDE | |
| 154 { | |
| 155 WorkerGlobalScope* workerGlobalScope = m_workerThread.workerGlobalScope(
); | |
| 156 // Tasks could be put on the message loop after the cleanup task, | |
| 157 // ensure none of those are ran. | |
| 158 if (!workerGlobalScope) | |
| 159 return; | |
| 160 | |
| 161 if (m_isInstrumented) | |
| 162 InspectorInstrumentation::willPerformExecutionContextTask(workerGlob
alScope, m_task.get()); | |
| 163 if ((!workerGlobalScope->isClosing() && !m_workerThread.terminated()) ||
m_task->isCleanupTask()) | |
| 164 m_task->performTask(workerGlobalScope); | |
| 165 if (m_isInstrumented) | |
| 166 InspectorInstrumentation::didPerformExecutionContextTask(workerGloba
lScope); | |
| 167 } | |
| 168 | |
| 169 private: | |
| 170 WorkerThreadTask(const WorkerThread& workerThread, PassOwnPtr<ExecutionConte
xtTask> task, bool isInstrumented) | |
| 171 : m_workerThread(workerThread) | |
| 172 , m_task(task) | |
| 173 , m_isInstrumented(isInstrumented) | |
| 174 { | |
| 175 if (m_isInstrumented) | |
| 176 m_isInstrumented = !m_task->taskNameForInstrumentation().isEmpty(); | |
| 177 if (m_isInstrumented) | |
| 178 InspectorInstrumentation::didPostExecutionContextTask(m_workerThread
.workerGlobalScope(), m_task.get()); | |
| 179 } | |
| 180 | |
| 181 const WorkerThread& m_workerThread; | |
| 182 OwnPtr<ExecutionContextTask> m_task; | |
| 183 bool m_isInstrumented; | |
| 184 }; | |
| 185 | 217 |
| 186 class RunDebuggerQueueTask FINAL : public ExecutionContextTask { | 218 class RunDebuggerQueueTask FINAL : public ExecutionContextTask { |
| 187 public: | 219 public: |
| 188 static PassOwnPtr<RunDebuggerQueueTask> create(WorkerThread* thread) | 220 static PassOwnPtr<RunDebuggerQueueTask> create(WorkerThread* thread) |
| 189 { | 221 { |
| 190 return adoptPtr(new RunDebuggerQueueTask(thread)); | 222 return adoptPtr(new RunDebuggerQueueTask(thread)); |
| 191 } | 223 } |
| 192 virtual void performTask(ExecutionContext* context) OVERRIDE | 224 virtual void performTask(ExecutionContext* context) OVERRIDE |
| 193 { | 225 { |
| 194 ASSERT(context->isWorkerGlobalScope()); | 226 ASSERT(context->isWorkerGlobalScope()); |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 445 void WorkerThread::postTask(PassOwnPtr<ExecutionContextTask> task) | 477 void WorkerThread::postTask(PassOwnPtr<ExecutionContextTask> task) |
| 446 { | 478 { |
| 447 m_thread->postTask(WorkerThreadTask::create(*this, task, true).leakPtr()); | 479 m_thread->postTask(WorkerThreadTask::create(*this, task, true).leakPtr()); |
| 448 } | 480 } |
| 449 | 481 |
| 450 void WorkerThread::postDelayedTask(PassOwnPtr<ExecutionContextTask> task, long l
ong delayMs) | 482 void WorkerThread::postDelayedTask(PassOwnPtr<ExecutionContextTask> task, long l
ong delayMs) |
| 451 { | 483 { |
| 452 m_thread->postDelayedTask(WorkerThreadTask::create(*this, task, true).leakPt
r(), delayMs); | 484 m_thread->postDelayedTask(WorkerThreadTask::create(*this, task, true).leakPt
r(), delayMs); |
| 453 } | 485 } |
| 454 | 486 |
| 487 void WorkerThread::postCancellableDelayedTask(WorkerThreadTask* task, long long
delayMs) |
| 488 { |
| 489 m_thread->postCancellableDelayedTask(task->weakPtrFactory(), delayMs); |
| 490 } |
| 491 |
| 455 void WorkerThread::postDebuggerTask(PassOwnPtr<ExecutionContextTask> task) | 492 void WorkerThread::postDebuggerTask(PassOwnPtr<ExecutionContextTask> task) |
| 456 { | 493 { |
| 457 m_debuggerMessageQueue.append(WorkerThreadTask::create(*this, task, false)); | 494 m_debuggerMessageQueue.append(WorkerThreadTask::create(*this, task, false)); |
| 458 postTask(RunDebuggerQueueTask::create(this)); | 495 postTask(RunDebuggerQueueTask::create(this)); |
| 459 } | 496 } |
| 460 | 497 |
| 461 MessageQueueWaitResult WorkerThread::runDebuggerTask(WaitMode waitMode) | 498 MessageQueueWaitResult WorkerThread::runDebuggerTask(WaitMode waitMode) |
| 462 { | 499 { |
| 463 ASSERT(isCurrentThread()); | 500 ASSERT(isCurrentThread()); |
| 464 MessageQueueWaitResult result; | 501 MessageQueueWaitResult result; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 490 InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get()); | 527 InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get()); |
| 491 } | 528 } |
| 492 | 529 |
| 493 void WorkerThread::setWorkerInspectorController(WorkerInspectorController* worke
rInspectorController) | 530 void WorkerThread::setWorkerInspectorController(WorkerInspectorController* worke
rInspectorController) |
| 494 { | 531 { |
| 495 MutexLocker locker(m_workerInspectorControllerMutex); | 532 MutexLocker locker(m_workerInspectorControllerMutex); |
| 496 m_workerInspectorController = workerInspectorController; | 533 m_workerInspectorController = workerInspectorController; |
| 497 } | 534 } |
| 498 | 535 |
| 499 } // namespace blink | 536 } // namespace blink |
| OLD | NEW |