OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/device_orientation/data_fetcher_shared_memory_base.h" | 5 #include "content/browser/device_orientation/data_fetcher_shared_memory_base.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
10 #include "base/threading/thread.h" | 10 #include "base/threading/thread.h" |
11 #include "base/timer/timer.h" | 11 #include "base/timer/timer.h" |
12 | 12 |
13 namespace content { | 13 namespace content { |
14 | 14 |
15 namespace { | 15 namespace { |
16 const int kPeriodInMilliseconds = 100; | 16 const int kPeriodInMilliseconds = 100; |
17 } | 17 } |
18 | 18 |
19 class DataFetcherSharedMemoryBase::PollingThread : public base::Thread { | 19 class DataFetcherSharedMemoryBase::PollingThread : public base::Thread { |
20 public: | 20 public: |
21 PollingThread(const char* name, DataFetcherSharedMemoryBase* fetcher); | 21 PollingThread(const char* name, DataFetcherSharedMemoryBase* fetcher); |
22 virtual ~PollingThread(); | 22 virtual ~PollingThread(); |
23 | 23 |
24 void SetConsumers(int consumers_bitmask); | 24 void AddConsumer(ConsumerType consumer_type); |
| 25 void RemoveConsumer(ConsumerType consumer_type); |
| 26 |
25 unsigned GetConsumersBitmask() const { return consumers_bitmask_; } | 27 unsigned GetConsumersBitmask() const { return consumers_bitmask_; } |
26 | 28 |
27 private: | 29 private: |
28 | 30 |
29 void DoPoll(); | 31 void DoPoll(); |
30 | 32 |
31 unsigned consumers_bitmask_; | 33 unsigned consumers_bitmask_; |
32 DataFetcherSharedMemoryBase* fetcher_; | 34 DataFetcherSharedMemoryBase* fetcher_; |
33 scoped_ptr<base::RepeatingTimer<PollingThread> > timer_; | 35 scoped_ptr<base::RepeatingTimer<PollingThread> > timer_; |
34 | 36 |
35 DISALLOW_COPY_AND_ASSIGN(PollingThread); | 37 DISALLOW_COPY_AND_ASSIGN(PollingThread); |
36 }; | 38 }; |
37 | 39 |
38 // --- PollingThread methods | 40 // --- PollingThread methods |
39 | 41 |
40 DataFetcherSharedMemoryBase::PollingThread::PollingThread( | 42 DataFetcherSharedMemoryBase::PollingThread::PollingThread( |
41 const char* name, DataFetcherSharedMemoryBase* fetcher) | 43 const char* name, DataFetcherSharedMemoryBase* fetcher) |
42 : base::Thread(name), consumers_bitmask_(0), fetcher_(fetcher) { | 44 : base::Thread(name), consumers_bitmask_(0), fetcher_(fetcher) { |
43 } | 45 } |
44 | 46 |
45 DataFetcherSharedMemoryBase::PollingThread::~PollingThread() { | 47 DataFetcherSharedMemoryBase::PollingThread::~PollingThread() { |
46 } | 48 } |
47 | 49 |
48 void DataFetcherSharedMemoryBase::PollingThread::SetConsumers( | 50 void DataFetcherSharedMemoryBase::PollingThread::AddConsumer( |
49 int consumers_bitmask) { | 51 ConsumerType consumer_type) { |
50 consumers_bitmask_ = consumers_bitmask; | 52 DCHECK(fetcher_); |
51 if (!consumers_bitmask_) { | 53 if (!fetcher_->Start(consumer_type)) |
52 timer_.reset(); // will also stop the timer. | |
53 return; | 54 return; |
54 } | 55 |
| 56 consumers_bitmask_ |= consumer_type; |
55 | 57 |
56 if (!timer_) | 58 if (!timer_) |
57 timer_.reset(new base::RepeatingTimer<PollingThread>()); | 59 timer_.reset(new base::RepeatingTimer<PollingThread>()); |
58 | 60 |
59 timer_->Start(FROM_HERE, | 61 timer_->Start(FROM_HERE, |
60 base::TimeDelta::FromMilliseconds(kPeriodInMilliseconds), | 62 base::TimeDelta::FromMilliseconds(kPeriodInMilliseconds), |
61 this, &PollingThread::DoPoll); | 63 this, &PollingThread::DoPoll); |
62 } | 64 } |
63 | 65 |
| 66 void DataFetcherSharedMemoryBase::PollingThread::RemoveConsumer( |
| 67 ConsumerType consumer_type) { |
| 68 DCHECK(fetcher_); |
| 69 if (!fetcher_->Stop(consumer_type)) |
| 70 return; |
| 71 |
| 72 consumers_bitmask_ ^= consumer_type; |
| 73 |
| 74 if (!consumers_bitmask_) |
| 75 timer_.reset(); // will also stop the timer. |
| 76 } |
| 77 |
64 void DataFetcherSharedMemoryBase::PollingThread::DoPoll() { | 78 void DataFetcherSharedMemoryBase::PollingThread::DoPoll() { |
65 DCHECK(fetcher_); | 79 DCHECK(fetcher_); |
66 DCHECK(consumers_bitmask_); | 80 DCHECK(consumers_bitmask_); |
67 fetcher_->Fetch(consumers_bitmask_); | 81 fetcher_->Fetch(consumers_bitmask_); |
68 } | 82 } |
69 | 83 |
70 // --- end of PollingThread methods | 84 // --- end of PollingThread methods |
71 | 85 |
72 DataFetcherSharedMemoryBase::DataFetcherSharedMemoryBase() | 86 DataFetcherSharedMemoryBase::DataFetcherSharedMemoryBase() |
73 : started_consumers_(0) { | 87 : started_consumers_(0) { |
74 } | 88 } |
75 | 89 |
76 DataFetcherSharedMemoryBase::~DataFetcherSharedMemoryBase() { | 90 DataFetcherSharedMemoryBase::~DataFetcherSharedMemoryBase() { |
77 StopFetchingDeviceData(CONSUMER_TYPE_MOTION); | 91 StopFetchingDeviceData(CONSUMER_TYPE_MOTION); |
78 StopFetchingDeviceData(CONSUMER_TYPE_ORIENTATION); | 92 StopFetchingDeviceData(CONSUMER_TYPE_ORIENTATION); |
79 | 93 |
80 // make sure polling thread stops asap. | 94 // make sure polling thread stops asap. |
81 if (polling_thread_) | 95 if (polling_thread_) |
82 polling_thread_->Stop(); | 96 polling_thread_->Stop(); |
83 | 97 |
84 STLDeleteContainerPairSecondPointers(shared_memory_map_.begin(), | 98 STLDeleteContainerPairSecondPointers(shared_memory_map_.begin(), |
85 shared_memory_map_.end()); | 99 shared_memory_map_.end()); |
86 } | 100 } |
87 | 101 |
88 bool DataFetcherSharedMemoryBase::StartFetchingDeviceData( | 102 bool DataFetcherSharedMemoryBase::StartFetchingDeviceData( |
89 ConsumerType consumer_type) { | 103 ConsumerType consumer_type) { |
90 if (started_consumers_ & consumer_type) | 104 if (started_consumers_ & consumer_type) |
91 return true; | 105 return true; |
92 | 106 |
93 if (!Start(consumer_type)) | 107 if (IsPolling()) { |
94 return false; | 108 if (!InitAndStartPollingThreadIfNecessary()) |
| 109 return false; |
| 110 polling_thread_->message_loop()->PostTask( |
| 111 FROM_HERE, |
| 112 base::Bind(&PollingThread::AddConsumer, |
| 113 base::Unretained(polling_thread_.get()), |
| 114 consumer_type)); |
| 115 } else { |
| 116 if (!Start(consumer_type)) |
| 117 return false; |
| 118 } |
95 | 119 |
96 started_consumers_ |= consumer_type; | 120 started_consumers_ |= consumer_type; |
97 | 121 |
98 if (IsPolling()) { | |
99 if (!InitAndStartPollingThreadIfNecessary()) { | |
100 Stop(consumer_type); | |
101 started_consumers_ ^= consumer_type; | |
102 return false; | |
103 } | |
104 polling_thread_->message_loop()->PostTask( | |
105 FROM_HERE, | |
106 base::Bind(&PollingThread::SetConsumers, | |
107 base::Unretained(polling_thread_.get()), | |
108 started_consumers_)); | |
109 } | |
110 return true; | 122 return true; |
111 } | 123 } |
112 | 124 |
113 bool DataFetcherSharedMemoryBase::StopFetchingDeviceData( | 125 bool DataFetcherSharedMemoryBase::StopFetchingDeviceData( |
114 ConsumerType consumer_type) { | 126 ConsumerType consumer_type) { |
115 if (!(started_consumers_ & consumer_type)) | 127 if (!(started_consumers_ & consumer_type)) |
116 return true; | 128 return true; |
117 | 129 |
118 if (!Stop(consumer_type)) | |
119 return false; | |
120 | |
121 started_consumers_ ^= consumer_type; | |
122 | |
123 if (IsPolling()) { | 130 if (IsPolling()) { |
124 polling_thread_->message_loop()->PostTask( | 131 polling_thread_->message_loop()->PostTask( |
125 FROM_HERE, | 132 FROM_HERE, |
126 base::Bind(&PollingThread::SetConsumers, | 133 base::Bind(&PollingThread::RemoveConsumer, |
127 base::Unretained(polling_thread_.get()), | 134 base::Unretained(polling_thread_.get()), |
128 started_consumers_)); | 135 consumer_type)); |
| 136 } else { |
| 137 if (!Stop(consumer_type)) |
| 138 return false; |
129 } | 139 } |
| 140 |
| 141 started_consumers_ ^= consumer_type; |
| 142 |
130 return true; | 143 return true; |
131 } | 144 } |
132 | 145 |
133 base::SharedMemoryHandle | 146 base::SharedMemoryHandle |
134 DataFetcherSharedMemoryBase::GetSharedMemoryHandleForProcess( | 147 DataFetcherSharedMemoryBase::GetSharedMemoryHandleForProcess( |
135 ConsumerType consumer_type, base::ProcessHandle process) { | 148 ConsumerType consumer_type, base::ProcessHandle process) { |
136 SharedMemoryMap::const_iterator it = shared_memory_map_.find(consumer_type); | 149 SharedMemoryMap::const_iterator it = shared_memory_map_.find(consumer_type); |
137 if (it == shared_memory_map_.end()) | 150 if (it == shared_memory_map_.end()) |
138 return base::SharedMemory::NULLHandle(); | 151 return base::SharedMemory::NULLHandle(); |
139 | 152 |
(...skipping 23 matching lines...) Expand all Loading... |
163 bool DataFetcherSharedMemoryBase::IsPolling() const { | 176 bool DataFetcherSharedMemoryBase::IsPolling() const { |
164 return false; | 177 return false; |
165 } | 178 } |
166 | 179 |
167 base::SharedMemory* DataFetcherSharedMemoryBase::InitSharedMemory( | 180 base::SharedMemory* DataFetcherSharedMemoryBase::InitSharedMemory( |
168 ConsumerType consumer_type, size_t buffer_size) { | 181 ConsumerType consumer_type, size_t buffer_size) { |
169 SharedMemoryMap::const_iterator it = shared_memory_map_.find(consumer_type); | 182 SharedMemoryMap::const_iterator it = shared_memory_map_.find(consumer_type); |
170 if (it != shared_memory_map_.end()) | 183 if (it != shared_memory_map_.end()) |
171 return it->second; | 184 return it->second; |
172 | 185 |
173 base::SharedMemory* new_shared_mem = new base::SharedMemory; | 186 scoped_ptr<base::SharedMemory> new_shared_mem(new base::SharedMemory); |
174 if (new_shared_mem->CreateAndMapAnonymous(buffer_size)) { | 187 if (new_shared_mem->CreateAndMapAnonymous(buffer_size)) { |
175 if (void* mem = new_shared_mem->memory()) { | 188 if (void* mem = new_shared_mem->memory()) { |
176 memset(mem, 0, buffer_size); | 189 memset(mem, 0, buffer_size); |
177 shared_memory_map_[consumer_type] = new_shared_mem; | 190 base::SharedMemory* shared_mem = new_shared_mem.release(); |
178 return new_shared_mem; | 191 shared_memory_map_[consumer_type] = shared_mem; |
| 192 return shared_mem; |
179 } | 193 } |
180 } | 194 } |
181 LOG(ERROR) << "Failed to initialize shared memory"; | 195 LOG(ERROR) << "Failed to initialize shared memory"; |
182 return NULL; | 196 return NULL; |
183 } | 197 } |
184 | 198 |
185 void* DataFetcherSharedMemoryBase::InitSharedMemoryBuffer( | 199 void* DataFetcherSharedMemoryBase::InitSharedMemoryBuffer( |
186 ConsumerType consumer_type, size_t buffer_size) { | 200 ConsumerType consumer_type, size_t buffer_size) { |
187 if (base::SharedMemory* shared_memory = InitSharedMemory(consumer_type, | 201 if (base::SharedMemory* shared_memory = InitSharedMemory(consumer_type, |
188 buffer_size)) | 202 buffer_size)) |
189 return shared_memory->memory(); | 203 return shared_memory->memory(); |
190 return NULL; | 204 return NULL; |
191 } | 205 } |
192 | 206 |
193 base::MessageLoop* DataFetcherSharedMemoryBase::GetPollingMessageLoop() const { | 207 base::MessageLoop* DataFetcherSharedMemoryBase::GetPollingMessageLoop() const { |
194 return polling_thread_ ? polling_thread_->message_loop() : NULL; | 208 return polling_thread_ ? polling_thread_->message_loop() : NULL; |
195 } | 209 } |
196 | 210 |
197 } // namespace content | 211 } // namespace content |
OLD | NEW |