Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(668)

Side by Side Diff: Source/core/workers/WorkerThread.cpp

Issue 563203002: [Blink-WebWorkers] WorkerSharedTimer cancels extra delayed tasks. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Removed hash set, which was used to store previous tasks. Now using single ptr. Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698