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 WorkerThreadCancelableTask FINAL : public ExecutionContextTask { | |
89 WTF_MAKE_NONCOPYABLE(WorkerThreadCancelableTask); WTF_MAKE_FAST_ALLOCATED; | |
90 public: | |
91 static PassOwnPtr<WorkerThreadCancelableTask> create(const Closure& closure) | |
92 { | |
93 return adoptPtr(new WorkerThreadCancelableTask(closure)); | |
94 } | |
95 | |
96 virtual void performTask(ExecutionContext*) OVERRIDE | |
97 { | |
98 if (!m_taskCanceled) | |
99 m_closure(); | |
100 } | |
101 | |
102 void cancelTask() { m_taskCanceled = true; } | |
103 | |
104 private: | |
105 explicit WorkerThreadCancelableTask(const Closure& closure) | |
106 : m_closure(closure) | |
107 , m_taskCanceled(false) | |
108 { } | |
109 | |
110 Closure m_closure; | |
111 bool m_taskCanceled; | |
112 }; | |
113 | |
88 class WorkerSharedTimer : public SharedTimer { | 114 class WorkerSharedTimer : public SharedTimer { |
89 public: | 115 public: |
90 explicit WorkerSharedTimer(WorkerThread* workerThread) | 116 explicit WorkerSharedTimer(WorkerThread* workerThread) |
91 : m_workerThread(workerThread) | 117 : m_workerThread(workerThread) |
92 , m_nextFireTime(0.0) | 118 , m_nextFireTime(0.0) |
93 , m_running(false) | 119 , m_running(false) |
120 , m_lastQueuedTask(0) | |
121 , m_lastQueuedTaskTimer(0) | |
94 { } | 122 { } |
95 | 123 |
96 typedef void (*SharedTimerFunction)(); | 124 typedef void (*SharedTimerFunction)(); |
97 virtual void setFiredFunction(SharedTimerFunction func) | 125 virtual void setFiredFunction(SharedTimerFunction func) |
98 { | 126 { |
99 m_sharedTimerFunction = func; | 127 m_sharedTimerFunction = func; |
100 if (!m_sharedTimerFunction) | 128 if (!m_sharedTimerFunction) |
101 m_nextFireTime = 0.0; | 129 m_nextFireTime = 0.0; |
102 } | 130 } |
103 | 131 |
104 virtual void setFireInterval(double interval) | 132 virtual void setFireInterval(double interval) |
jochen (gone - plz use gerrit)
2014/09/16 14:17:04
assume the following two calls happen:
setFireInt
| |
105 { | 133 { |
106 ASSERT(m_sharedTimerFunction); | 134 ASSERT(m_sharedTimerFunction); |
107 | 135 |
108 // See BlinkPlatformImpl::setSharedTimerFireInterval for explanation of | 136 // See BlinkPlatformImpl::setSharedTimerFireInterval for explanation of |
109 // why ceil is used in the interval calculation. | 137 // why ceil is used in the interval calculation. |
110 int64 delay = static_cast<int64>(ceil(interval * 1000)); | 138 int64 delay = static_cast<int64>(ceil(interval * 1000)); |
111 | 139 |
112 if (delay < 0) { | 140 if (delay < 0) { |
113 delay = 0; | 141 delay = 0; |
114 m_nextFireTime = 0.0; | 142 m_nextFireTime = 0.0; |
115 } | 143 } |
116 | 144 |
117 m_running = true; | 145 m_running = true; |
118 m_nextFireTime = currentTime() + interval; | 146 m_nextFireTime = currentTime() + interval; |
119 m_workerThread->postDelayedTask(createSameThreadTask(&WorkerSharedTimer: :OnTimeout, this), delay); | 147 if (m_lastQueuedTask) { |
148 // If something was queued up before this, check if its later than t he current timer | |
149 if (interval < m_lastQueuedTaskTimer->nextFireInterval()) { | |
150 m_lastQueuedTask->cancelTask(); | |
151 m_lastQueuedTask = 0; | |
152 m_lastQueuedTaskTimer = 0; | |
153 } | |
154 } | |
155 if (!m_lastQueuedTask) { | |
156 // Now queue the task as a cancellable one. | |
157 m_lastQueuedTask = WorkerThreadCancelableTask::create(bind(&WorkerSh aredTimer::OnTimeout, this)).leakPtr(); | |
158 m_workerThread->postDelayedTask(adoptPtr(m_lastQueuedTask), delay); | |
159 // The current timer should ideally be at the top of the heap as its assumed to be the smallest interval in the heap | |
160 m_lastQueuedTaskTimer = PlatformThreadData::current().threadTimers() .timerHeap().first(); | |
161 } | |
120 } | 162 } |
121 | 163 |
122 virtual void stop() | 164 virtual void stop() |
123 { | 165 { |
124 m_running = false; | 166 m_running = false; |
167 m_lastQueuedTask = 0; | |
168 m_lastQueuedTaskTimer = 0; | |
125 } | 169 } |
126 | 170 |
127 double nextFireTime() { return m_nextFireTime; } | 171 double nextFireTime() { return m_nextFireTime; } |
128 | 172 |
129 private: | 173 private: |
130 void OnTimeout() | 174 void OnTimeout() |
131 { | 175 { |
132 ASSERT(m_workerThread->workerGlobalScope()); | 176 ASSERT(m_workerThread->workerGlobalScope()); |
177 | |
178 m_lastQueuedTask = 0; | |
179 m_lastQueuedTaskTimer = 0; | |
180 | |
133 if (m_sharedTimerFunction && m_running && !m_workerThread->workerGlobalS cope()->isClosing()) | 181 if (m_sharedTimerFunction && m_running && !m_workerThread->workerGlobalS cope()->isClosing()) |
134 m_sharedTimerFunction(); | 182 m_sharedTimerFunction(); |
135 } | 183 } |
136 | 184 |
137 WorkerThread* m_workerThread; | 185 WorkerThread* m_workerThread; |
138 SharedTimerFunction m_sharedTimerFunction; | 186 SharedTimerFunction m_sharedTimerFunction; |
139 double m_nextFireTime; | 187 double m_nextFireTime; |
140 bool m_running; | 188 bool m_running; |
189 WorkerThreadCancelableTask* m_lastQueuedTask; | |
190 TimerBase* m_lastQueuedTaskTimer; | |
141 }; | 191 }; |
142 | 192 |
143 class WorkerThreadTask : public blink::WebThread::Task { | 193 class WorkerThreadTask : public blink::WebThread::Task { |
144 WTF_MAKE_NONCOPYABLE(WorkerThreadTask); WTF_MAKE_FAST_ALLOCATED; | 194 WTF_MAKE_NONCOPYABLE(WorkerThreadTask); WTF_MAKE_FAST_ALLOCATED; |
145 public: | 195 public: |
146 static PassOwnPtr<WorkerThreadTask> create(const WorkerThread& workerThread, PassOwnPtr<ExecutionContextTask> task, bool isInstrumented) | 196 static PassOwnPtr<WorkerThreadTask> create(const WorkerThread& workerThread, PassOwnPtr<ExecutionContextTask> task, bool isInstrumented) |
147 { | 197 { |
148 return adoptPtr(new WorkerThreadTask(workerThread, task, isInstrumented) ); | 198 return adoptPtr(new WorkerThreadTask(workerThread, task, isInstrumented) ); |
149 } | 199 } |
150 | 200 |
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
496 InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get()); | 546 InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get()); |
497 } | 547 } |
498 | 548 |
499 void WorkerThread::setWorkerInspectorController(WorkerInspectorController* worke rInspectorController) | 549 void WorkerThread::setWorkerInspectorController(WorkerInspectorController* worke rInspectorController) |
500 { | 550 { |
501 MutexLocker locker(m_workerInspectorControllerMutex); | 551 MutexLocker locker(m_workerInspectorControllerMutex); |
502 m_workerInspectorController = workerInspectorController; | 552 m_workerInspectorController = workerInspectorController; |
503 } | 553 } |
504 | 554 |
505 } // namespace blink | 555 } // namespace blink |
OLD | NEW |