| 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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 188 buffer_size)) | 201 buffer_size)) |
| 189 return shared_memory->memory(); | 202 return shared_memory->memory(); |
| 190 return NULL; | 203 return NULL; |
| 191 } | 204 } |
| 192 | 205 |
| 193 base::MessageLoop* DataFetcherSharedMemoryBase::GetPollingMessageLoop() const { | 206 base::MessageLoop* DataFetcherSharedMemoryBase::GetPollingMessageLoop() const { |
| 194 return polling_thread_ ? polling_thread_->message_loop() : NULL; | 207 return polling_thread_ ? polling_thread_->message_loop() : NULL; |
| 195 } | 208 } |
| 196 | 209 |
| 197 } // namespace content | 210 } // namespace content |
| OLD | NEW |