• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2010 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/browser/sync/notifier/chrome_system_resources.h"
6 
7 #include <cstdlib>
8 #include <cstring>
9 #include <string>
10 
11 #include "base/logging.h"
12 #include "base/message_loop.h"
13 #include "base/stl_util-inl.h"
14 #include "base/string_util.h"
15 #include "base/stringprintf.h"
16 #include "chrome/browser/sync/notifier/invalidation_util.h"
17 
18 namespace sync_notifier {
19 
ChromeSystemResources(StateWriter * state_writer)20 ChromeSystemResources::ChromeSystemResources(StateWriter* state_writer)
21     : state_writer_(state_writer),
22       created_on_loop_(MessageLoop::current()) {
23   DCHECK(non_thread_safe_.CalledOnValidThread());
24   CHECK(created_on_loop_);
25   DCHECK(state_writer_);
26 }
27 
~ChromeSystemResources()28 ChromeSystemResources::~ChromeSystemResources() {
29   DCHECK(non_thread_safe_.CalledOnValidThread());
30   CHECK_EQ(created_on_loop_, MessageLoop::current());
31   StopScheduler();
32 }
33 
current_time()34 invalidation::Time ChromeSystemResources::current_time() {
35   DCHECK(non_thread_safe_.CalledOnValidThread());
36   CHECK_EQ(created_on_loop_, MessageLoop::current());
37   return base::Time::Now();
38 }
39 
StartScheduler()40 void ChromeSystemResources::StartScheduler() {
41   DCHECK(non_thread_safe_.CalledOnValidThread());
42   CHECK_EQ(created_on_loop_, MessageLoop::current());
43   scoped_runnable_method_factory_.reset(
44       new ScopedRunnableMethodFactory<ChromeSystemResources>(this));
45 }
46 
StopScheduler()47 void ChromeSystemResources::StopScheduler() {
48   DCHECK(non_thread_safe_.CalledOnValidThread());
49   CHECK_EQ(created_on_loop_, MessageLoop::current());
50   scoped_runnable_method_factory_.reset();
51   STLDeleteElements(&posted_tasks_);
52 }
53 
ScheduleWithDelay(invalidation::TimeDelta delay,invalidation::Closure * task)54 void ChromeSystemResources::ScheduleWithDelay(
55     invalidation::TimeDelta delay,
56     invalidation::Closure* task) {
57   DCHECK(non_thread_safe_.CalledOnValidThread());
58   CHECK_EQ(created_on_loop_, MessageLoop::current());
59   Task* task_to_post = MakeTaskToPost(task);
60   if (!task_to_post) {
61     return;
62   }
63   MessageLoop::current()->PostDelayedTask(
64       FROM_HERE, task_to_post, delay.InMillisecondsRoundedUp());
65 }
66 
ScheduleImmediately(invalidation::Closure * task)67 void ChromeSystemResources::ScheduleImmediately(
68     invalidation::Closure* task) {
69   DCHECK(non_thread_safe_.CalledOnValidThread());
70   CHECK_EQ(created_on_loop_, MessageLoop::current());
71   Task* task_to_post = MakeTaskToPost(task);
72   if (!task_to_post) {
73     return;
74   }
75   MessageLoop::current()->PostTask(FROM_HERE, task_to_post);
76 }
77 
78 // The listener thread is just our current thread (i.e., the
79 // notifications thread).
ScheduleOnListenerThread(invalidation::Closure * task)80 void ChromeSystemResources::ScheduleOnListenerThread(
81     invalidation::Closure* task) {
82   DCHECK(non_thread_safe_.CalledOnValidThread());
83   CHECK_EQ(created_on_loop_, MessageLoop::current());
84   ScheduleImmediately(task);
85 }
86 
87 // 'Internal thread' means 'not the listener thread'.  Since the
88 // listener thread is the notifications thread, always return false.
IsRunningOnInternalThread()89 bool ChromeSystemResources::IsRunningOnInternalThread() {
90   DCHECK(non_thread_safe_.CalledOnValidThread());
91   CHECK_EQ(created_on_loop_, MessageLoop::current());
92   return false;
93 }
94 
Log(LogLevel level,const char * file,int line,const char * format,...)95 void ChromeSystemResources::Log(
96     LogLevel level, const char* file, int line,
97     const char* format, ...) {
98   DCHECK(non_thread_safe_.CalledOnValidThread());
99   logging::LogSeverity log_severity = logging::LOG_INFO;
100   switch (level) {
101     case INFO_LEVEL:
102       log_severity = logging::LOG_INFO;
103       break;
104     case WARNING_LEVEL:
105       log_severity = logging::LOG_WARNING;
106       break;
107     case SEVERE_LEVEL:
108       log_severity = logging::LOG_ERROR;
109       break;
110   }
111   // We treat LOG(INFO) as VLOG(1).
112   if ((log_severity >= logging::GetMinLogLevel()) &&
113       ((log_severity != logging::LOG_INFO) ||
114        (1 <= logging::GetVlogLevelHelper(file, ::strlen(file))))) {
115     va_list ap;
116     va_start(ap, format);
117     std::string result;
118     base::StringAppendV(&result, format, ap);
119     logging::LogMessage(file, line, log_severity).stream() << result;
120     va_end(ap);
121   }
122 }
123 
RunAndDeleteStorageCallback(invalidation::StorageCallback * callback)124 void ChromeSystemResources::RunAndDeleteStorageCallback(
125     invalidation::StorageCallback* callback) {
126   callback->Run(true);
127   delete callback;
128 }
129 
WriteState(const invalidation::string & state,invalidation::StorageCallback * callback)130 void ChromeSystemResources::WriteState(
131     const invalidation::string& state,
132     invalidation::StorageCallback* callback) {
133   CHECK(state_writer_);
134   state_writer_->WriteState(state);
135   // According to the cache invalidation API folks, we can do this as
136   // long as we make sure to clear the persistent state that we start
137   // up the cache invalidation client with.  However, we musn't do it
138   // right away, as we may be called under a lock that the callback
139   // uses.
140   ScheduleImmediately(
141       invalidation::NewPermanentCallback(
142           this, &ChromeSystemResources::RunAndDeleteStorageCallback,
143           callback));
144 }
145 
MakeTaskToPost(invalidation::Closure * task)146 Task* ChromeSystemResources::MakeTaskToPost(
147     invalidation::Closure* task) {
148   DCHECK(non_thread_safe_.CalledOnValidThread());
149   DCHECK(invalidation::IsCallbackRepeatable(task));
150   CHECK_EQ(created_on_loop_, MessageLoop::current());
151   if (!scoped_runnable_method_factory_.get()) {
152     delete task;
153     return NULL;
154   }
155   posted_tasks_.insert(task);
156   Task* task_to_post =
157       scoped_runnable_method_factory_->NewRunnableMethod(
158           &ChromeSystemResources::RunPostedTask, task);
159   return task_to_post;
160 }
161 
RunPostedTask(invalidation::Closure * task)162 void ChromeSystemResources::RunPostedTask(invalidation::Closure* task) {
163   DCHECK(non_thread_safe_.CalledOnValidThread());
164   CHECK_EQ(created_on_loop_, MessageLoop::current());
165   RunAndDeleteClosure(task);
166   posted_tasks_.erase(task);
167 }
168 
169 }  // namespace sync_notifier
170