| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/common/worker_thread_ticker.h" | |
| 6 | |
| 7 #include <algorithm> | |
| 8 | |
| 9 #include "base/bind.h" | |
| 10 #include "base/bind_helpers.h" | |
| 11 #include "base/location.h" | |
| 12 #include "base/logging.h" | |
| 13 #include "base/single_thread_task_runner.h" | |
| 14 #include "base/threading/thread.h" | |
| 15 | |
| 16 WorkerThreadTicker::WorkerThreadTicker(int tick_interval) | |
| 17 : timer_thread_("worker_thread_ticker"), | |
| 18 is_running_(false), | |
| 19 tick_interval_(base::TimeDelta::FromMilliseconds(tick_interval)) { | |
| 20 } | |
| 21 | |
| 22 WorkerThreadTicker::~WorkerThreadTicker() { | |
| 23 Stop(); | |
| 24 } | |
| 25 | |
| 26 bool WorkerThreadTicker::RegisterTickHandler(Callback *tick_handler) { | |
| 27 DCHECK(tick_handler); | |
| 28 base::AutoLock lock(lock_); | |
| 29 // You cannot change the list of handlers when the timer is running. | |
| 30 // You need to call Stop first. | |
| 31 if (IsRunning()) | |
| 32 return false; | |
| 33 tick_handler_list_.push_back(tick_handler); | |
| 34 return true; | |
| 35 } | |
| 36 | |
| 37 bool WorkerThreadTicker::UnregisterTickHandler(Callback *tick_handler) { | |
| 38 DCHECK(tick_handler); | |
| 39 base::AutoLock lock(lock_); | |
| 40 // You cannot change the list of handlers when the timer is running. | |
| 41 // You need to call Stop first. | |
| 42 if (IsRunning()) { | |
| 43 return false; | |
| 44 } | |
| 45 TickHandlerListType::iterator index = std::remove(tick_handler_list_.begin(), | |
| 46 tick_handler_list_.end(), | |
| 47 tick_handler); | |
| 48 if (index == tick_handler_list_.end()) { | |
| 49 return false; | |
| 50 } | |
| 51 tick_handler_list_.erase(index, tick_handler_list_.end()); | |
| 52 return true; | |
| 53 } | |
| 54 | |
| 55 bool WorkerThreadTicker::Start() { | |
| 56 // Do this in a lock because we don't want 2 threads to | |
| 57 // call Start at the same time | |
| 58 base::AutoLock lock(lock_); | |
| 59 if (IsRunning()) | |
| 60 return false; | |
| 61 if (!timer_thread_.Start()) | |
| 62 return false; | |
| 63 is_running_ = true; | |
| 64 ScheduleTimerTask(); | |
| 65 return true; | |
| 66 } | |
| 67 | |
| 68 bool WorkerThreadTicker::Stop() { | |
| 69 // Do this in a lock because we don't want 2 threads to | |
| 70 // call Stop at the same time | |
| 71 base::AutoLock lock(lock_); | |
| 72 if (!IsRunning()) | |
| 73 return false; | |
| 74 is_running_ = false; | |
| 75 timer_thread_.Stop(); | |
| 76 return true; | |
| 77 } | |
| 78 | |
| 79 void WorkerThreadTicker::ScheduleTimerTask() { | |
| 80 timer_thread_.task_runner()->PostDelayedTask( | |
| 81 FROM_HERE, | |
| 82 base::Bind(&WorkerThreadTicker::TimerTask, base::Unretained(this)), | |
| 83 tick_interval_); | |
| 84 } | |
| 85 | |
| 86 void WorkerThreadTicker::TimerTask() { | |
| 87 // When the ticker is running, the handler list CANNOT be modified. | |
| 88 // So we can do the enumeration safely without a lock | |
| 89 const TickHandlerListType& handlers = tick_handler_list_; | |
| 90 for (TickHandlerListType::const_iterator i = handlers.begin(); | |
| 91 i != handlers.end(); ++i) { | |
| 92 (*i)->OnTick(); | |
| 93 } | |
| 94 | |
| 95 ScheduleTimerTask(); | |
| 96 } | |
| 97 | |
| OLD | NEW |