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 { | |
jochen (gone - plz use gerrit)
2014/09/15 14:29:41
why do you move this class up here?
Mayur Kankanwadi
2014/09/15 14:38:27
Was done to fix earlier compilation errors. Fixed
| |
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 private: | |
115 WorkerThreadTask(const WorkerThread& workerThread, PassOwnPtr<ExecutionConte xtTask> task, bool isInstrumented) | |
116 : m_workerThread(workerThread) | |
117 , m_task(task) | |
118 , m_isInstrumented(isInstrumented) | |
119 { | |
120 if (m_isInstrumented) | |
121 m_isInstrumented = !m_task->taskNameForInstrumentation().isEmpty(); | |
122 if (m_isInstrumented) | |
123 InspectorInstrumentation::didPostExecutionContextTask(m_workerThread .workerGlobalScope(), m_task.get()); | |
124 } | |
125 | |
126 const WorkerThread& m_workerThread; | |
127 OwnPtr<ExecutionContextTask> m_task; | |
128 bool m_isInstrumented; | |
129 }; | |
130 | |
131 class WorkerThreadCancelableTask FINAL : public ExecutionContextTask { | |
jochen (gone - plz use gerrit)
2014/09/15 14:29:42
add wtf_make_noncopyable and fast allocated macros
Mayur Kankanwadi
2014/09/15 14:38:27
Done.
| |
132 public: | |
133 static PassOwnPtr<WorkerThreadCancelableTask> create(const Closure& closure) | |
134 { | |
135 return adoptPtr(new WorkerThreadCancelableTask(closure)); | |
136 } | |
137 | |
138 virtual void performTask(ExecutionContext*) OVERRIDE | |
139 { | |
140 if (!m_taskCanceled) | |
141 m_closure(); | |
142 } | |
143 | |
144 void cancelTask() { m_taskCanceled = true; } | |
145 | |
146 private: | |
147 explicit WorkerThreadCancelableTask(const Closure& closure) | |
148 : m_closure(closure) | |
149 , m_taskCanceled(false) | |
150 { } | |
151 | |
152 Closure m_closure; | |
153 bool m_taskCanceled; | |
154 }; | |
155 | |
88 class WorkerSharedTimer : public SharedTimer { | 156 class WorkerSharedTimer : public SharedTimer { |
89 public: | 157 public: |
90 explicit WorkerSharedTimer(WorkerThread* workerThread) | 158 explicit WorkerSharedTimer(WorkerThread* workerThread) |
91 : m_workerThread(workerThread) | 159 : m_workerThread(workerThread) |
92 , m_nextFireTime(0.0) | 160 , m_nextFireTime(0.0) |
93 , m_running(false) | 161 , m_running(false) |
94 { } | 162 { } |
95 | 163 |
96 typedef void (*SharedTimerFunction)(); | 164 typedef void (*SharedTimerFunction)(); |
97 virtual void setFiredFunction(SharedTimerFunction func) | 165 virtual void setFiredFunction(SharedTimerFunction func) |
(...skipping 11 matching lines...) Expand all Loading... | |
109 // why ceil is used in the interval calculation. | 177 // why ceil is used in the interval calculation. |
110 int64 delay = static_cast<int64>(ceil(interval * 1000)); | 178 int64 delay = static_cast<int64>(ceil(interval * 1000)); |
111 | 179 |
112 if (delay < 0) { | 180 if (delay < 0) { |
113 delay = 0; | 181 delay = 0; |
114 m_nextFireTime = 0.0; | 182 m_nextFireTime = 0.0; |
115 } | 183 } |
116 | 184 |
117 m_running = true; | 185 m_running = true; |
118 m_nextFireTime = currentTime() + interval; | 186 m_nextFireTime = currentTime() + interval; |
119 m_workerThread->postDelayedTask(createSameThreadTask(&WorkerSharedTimer: :OnTimeout, this), delay); | 187 if (m_lastQueuedTask) { |
188 // If something was queued up before this, check if its later than t he current timer | |
189 if (interval < m_lastQueuedTaskTimer->nextFireInterval()) { | |
190 m_lastQueuedTask->cancelTask(); | |
191 m_lastQueuedTask = 0; | |
192 m_lastQueuedTaskTimer = 0; | |
193 } | |
194 } | |
195 if (!m_lastQueuedTask) { | |
196 // Now queue the task as a cancellable one. | |
197 m_lastQueuedTask = WorkerThreadCancelableTask::create(bind(&WorkerSh aredTimer::OnTimeout, this)).leakPtr(); | |
198 m_workerThread->postDelayedTask(adoptPtr(m_lastQueuedTask), delay); | |
199 // The current timer should ideally be at the top of the heap as its assumed to be the smallest interval in the heap | |
200 m_lastQueuedTaskTimer = PlatformThreadData::current().threadTimers() .timerHeap().first(); | |
201 } | |
120 } | 202 } |
121 | 203 |
122 virtual void stop() | 204 virtual void stop() |
123 { | 205 { |
124 m_running = false; | 206 m_running = false; |
207 m_lastQueuedTask = 0; | |
208 m_lastQueuedTaskTimer = 0; | |
125 } | 209 } |
126 | 210 |
127 double nextFireTime() { return m_nextFireTime; } | 211 double nextFireTime() { return m_nextFireTime; } |
128 | 212 |
129 private: | 213 private: |
130 void OnTimeout() | 214 void OnTimeout() |
131 { | 215 { |
132 ASSERT(m_workerThread->workerGlobalScope()); | 216 ASSERT(m_workerThread->workerGlobalScope()); |
217 | |
218 m_lastQueuedTask = 0; | |
219 m_lastQueuedTaskTimer = 0; | |
220 | |
133 if (m_sharedTimerFunction && m_running && !m_workerThread->workerGlobalS cope()->isClosing()) | 221 if (m_sharedTimerFunction && m_running && !m_workerThread->workerGlobalS cope()->isClosing()) |
134 m_sharedTimerFunction(); | 222 m_sharedTimerFunction(); |
135 } | 223 } |
136 | 224 |
137 WorkerThread* m_workerThread; | 225 WorkerThread* m_workerThread; |
138 SharedTimerFunction m_sharedTimerFunction; | 226 SharedTimerFunction m_sharedTimerFunction; |
139 double m_nextFireTime; | 227 double m_nextFireTime; |
140 bool m_running; | 228 bool m_running; |
229 static WorkerThreadCancelableTask* m_lastQueuedTask; | |
jochen (gone - plz use gerrit)
2014/09/15 14:29:42
why static? there can be several worker threads
Mayur Kankanwadi
2014/09/15 14:38:27
Yes, it's unnecessary.
Acknowledged.
| |
230 static TimerBase* m_lastQueuedTaskTimer; | |
141 }; | 231 }; |
142 | 232 |
143 class WorkerThreadTask : public blink::WebThread::Task { | 233 WorkerThreadCancelableTask* WorkerSharedTimer::m_lastQueuedTask = 0; |
144 WTF_MAKE_NONCOPYABLE(WorkerThreadTask); WTF_MAKE_FAST_ALLOCATED; | 234 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 | 235 |
186 class RunDebuggerQueueTask FINAL : public ExecutionContextTask { | 236 class RunDebuggerQueueTask FINAL : public ExecutionContextTask { |
187 public: | 237 public: |
188 static PassOwnPtr<RunDebuggerQueueTask> create(WorkerThread* thread) | 238 static PassOwnPtr<RunDebuggerQueueTask> create(WorkerThread* thread) |
189 { | 239 { |
190 return adoptPtr(new RunDebuggerQueueTask(thread)); | 240 return adoptPtr(new RunDebuggerQueueTask(thread)); |
191 } | 241 } |
192 virtual void performTask(ExecutionContext* context) OVERRIDE | 242 virtual void performTask(ExecutionContext* context) OVERRIDE |
193 { | 243 { |
194 ASSERT(context->isWorkerGlobalScope()); | 244 ASSERT(context->isWorkerGlobalScope()); |
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
490 InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get()); | 540 InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get()); |
491 } | 541 } |
492 | 542 |
493 void WorkerThread::setWorkerInspectorController(WorkerInspectorController* worke rInspectorController) | 543 void WorkerThread::setWorkerInspectorController(WorkerInspectorController* worke rInspectorController) |
494 { | 544 { |
495 MutexLocker locker(m_workerInspectorControllerMutex); | 545 MutexLocker locker(m_workerInspectorControllerMutex); |
496 m_workerInspectorController = workerInspectorController; | 546 m_workerInspectorController = workerInspectorController; |
497 } | 547 } |
498 | 548 |
499 } // namespace blink | 549 } // namespace blink |
OLD | NEW |