blob: 452a9ffc66e4831adedcf05f67cbabed55155537 [file] [log] [blame]
[email protected]d9b14782010-04-15 08:08:071// Copyright (c) 2010 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
initial.commit09911bf2008-07-26 23:55:295#include "chrome/common/worker_thread_ticker.h"
6
[email protected]d195f602009-01-14 17:23:197#include <algorithm>
8
9#include "base/logging.h"
[email protected]d9b14782010-04-15 08:08:0710#include "base/message_loop.h"
[email protected]d195f602009-01-14 17:23:1911#include "base/task.h"
[email protected]d195f602009-01-14 17:23:1912#include "base/thread.h"
13
14class WorkerThreadTicker::TimerTask : public Task {
15 public:
[email protected]4a3dab22009-11-11 17:36:5016 explicit TimerTask(WorkerThreadTicker* ticker) : ticker_(ticker) {
[email protected]d195f602009-01-14 17:23:1917 }
18
19 virtual void Run() {
20 // When the ticker is running, the handler list CANNOT be modified.
21 // So we can do the enumeration safely without a lock
22 TickHandlerListType* handlers = &ticker_->tick_handler_list_;
23 for (TickHandlerListType::const_iterator i = handlers->begin();
24 i != handlers->end(); ++i) {
25 (*i)->OnTick();
26 }
27
28 ticker_->ScheduleTimerTask();
29 }
30
31 private:
32 WorkerThreadTicker* ticker_;
33};
34
initial.commit09911bf2008-07-26 23:55:2935WorkerThreadTicker::WorkerThreadTicker(int tick_interval)
[email protected]d195f602009-01-14 17:23:1936 : timer_thread_("worker_thread_ticker"),
37 is_running_(false),
38 tick_interval_(tick_interval) {
initial.commit09911bf2008-07-26 23:55:2939}
40
41WorkerThreadTicker::~WorkerThreadTicker() {
42 Stop();
43}
44
45bool WorkerThreadTicker::RegisterTickHandler(Callback *tick_handler) {
46 DCHECK(tick_handler);
[email protected]d195f602009-01-14 17:23:1947 AutoLock lock(lock_);
initial.commit09911bf2008-07-26 23:55:2948 // You cannot change the list of handlers when the timer is running.
49 // You need to call Stop first.
[email protected]d195f602009-01-14 17:23:1950 if (IsRunning())
initial.commit09911bf2008-07-26 23:55:2951 return false;
initial.commit09911bf2008-07-26 23:55:2952 tick_handler_list_.push_back(tick_handler);
53 return true;
54}
55
56bool WorkerThreadTicker::UnregisterTickHandler(Callback *tick_handler) {
57 DCHECK(tick_handler);
[email protected]d195f602009-01-14 17:23:1958 AutoLock lock(lock_);
initial.commit09911bf2008-07-26 23:55:2959 // You cannot change the list of handlers when the timer is running.
60 // You need to call Stop first.
61 if (IsRunning()) {
62 return false;
63 }
64 TickHandlerListType::iterator index = std::remove(tick_handler_list_.begin(),
65 tick_handler_list_.end(),
66 tick_handler);
67 if (index == tick_handler_list_.end()) {
68 return false;
69 }
70 tick_handler_list_.erase(index, tick_handler_list_.end());
71 return true;
72}
73
74bool WorkerThreadTicker::Start() {
75 // Do this in a lock because we don't want 2 threads to
76 // call Start at the same time
[email protected]d195f602009-01-14 17:23:1977 AutoLock lock(lock_);
78 if (IsRunning())
initial.commit09911bf2008-07-26 23:55:2979 return false;
[email protected]6314e6f62009-07-15 16:07:1480 if (!timer_thread_.Start())
81 return false;
[email protected]d195f602009-01-14 17:23:1982 is_running_ = true;
[email protected]d195f602009-01-14 17:23:1983 ScheduleTimerTask();
84 return true;
initial.commit09911bf2008-07-26 23:55:2985}
86
87bool WorkerThreadTicker::Stop() {
88 // Do this in a lock because we don't want 2 threads to
89 // call Stop at the same time
[email protected]d195f602009-01-14 17:23:1990 AutoLock lock(lock_);
91 if (!IsRunning())
initial.commit09911bf2008-07-26 23:55:2992 return false;
[email protected]d195f602009-01-14 17:23:1993 is_running_ = false;
94 timer_thread_.Stop();
initial.commit09911bf2008-07-26 23:55:2995 return true;
96}
97
[email protected]d195f602009-01-14 17:23:1998void WorkerThreadTicker::ScheduleTimerTask() {
99 timer_thread_.message_loop()->PostDelayedTask(FROM_HERE, new TimerTask(this),
100 tick_interval_);
initial.commit09911bf2008-07-26 23:55:29101}