OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "chromecast/base/device_capabilities_impl.h" | 5 #include "chromecast/base/device_capabilities_impl.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <utility> |
8 | 9 |
9 #include "base/logging.h" | 10 #include "base/logging.h" |
10 #include "base/single_thread_task_runner.h" | 11 #include "base/single_thread_task_runner.h" |
11 #include "base/thread_task_runner_handle.h" | 12 #include "base/thread_task_runner_handle.h" |
12 #include "base/values.h" | 13 #include "base/values.h" |
13 #include "chromecast/base/serializers.h" | 14 #include "chromecast/base/serializers.h" |
14 | 15 |
15 namespace chromecast { | 16 namespace chromecast { |
16 | 17 |
17 namespace { | 18 namespace { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 return make_scoped_ptr(capabilities); | 64 return make_scoped_ptr(capabilities); |
64 } | 65 } |
65 | 66 |
66 scoped_refptr<DeviceCapabilities::Data> DeviceCapabilities::CreateData() { | 67 scoped_refptr<DeviceCapabilities::Data> DeviceCapabilities::CreateData() { |
67 return make_scoped_refptr(new Data); | 68 return make_scoped_refptr(new Data); |
68 } | 69 } |
69 | 70 |
70 scoped_refptr<DeviceCapabilities::Data> DeviceCapabilities::CreateData( | 71 scoped_refptr<DeviceCapabilities::Data> DeviceCapabilities::CreateData( |
71 scoped_ptr<const base::DictionaryValue> dictionary) { | 72 scoped_ptr<const base::DictionaryValue> dictionary) { |
72 DCHECK(dictionary.get()); | 73 DCHECK(dictionary.get()); |
73 return make_scoped_refptr(new Data(dictionary.Pass())); | 74 return make_scoped_refptr(new Data(std::move(dictionary))); |
74 } | 75 } |
75 | 76 |
76 DeviceCapabilities::Validator::Validator(DeviceCapabilities* capabilities) | 77 DeviceCapabilities::Validator::Validator(DeviceCapabilities* capabilities) |
77 : capabilities_(capabilities) { | 78 : capabilities_(capabilities) { |
78 DCHECK(capabilities); | 79 DCHECK(capabilities); |
79 } | 80 } |
80 | 81 |
81 void DeviceCapabilities::Validator::SetValidatedValue( | 82 void DeviceCapabilities::Validator::SetValidatedValue( |
82 const std::string& path, | 83 const std::string& path, |
83 scoped_ptr<base::Value> new_value) const { | 84 scoped_ptr<base::Value> new_value) const { |
84 capabilities_->SetValidatedValue(path, new_value.Pass()); | 85 capabilities_->SetValidatedValue(path, std::move(new_value)); |
85 } | 86 } |
86 | 87 |
87 DeviceCapabilities::Data::Data() | 88 DeviceCapabilities::Data::Data() |
88 : dictionary_(new base::DictionaryValue), | 89 : dictionary_(new base::DictionaryValue), |
89 json_string_(SerializeToJson(*dictionary_)) { | 90 json_string_(SerializeToJson(*dictionary_)) { |
90 DCHECK(json_string_.get()); | 91 DCHECK(json_string_.get()); |
91 } | 92 } |
92 | 93 |
93 DeviceCapabilities::Data::Data( | 94 DeviceCapabilities::Data::Data( |
94 scoped_ptr<const base::DictionaryValue> dictionary) | 95 scoped_ptr<const base::DictionaryValue> dictionary) |
95 : dictionary_(dictionary.Pass()), | 96 : dictionary_(std::move(dictionary)), |
96 json_string_(SerializeToJson(*dictionary_)) { | 97 json_string_(SerializeToJson(*dictionary_)) { |
97 DCHECK(dictionary_.get()); | 98 DCHECK(dictionary_.get()); |
98 DCHECK(json_string_.get()); | 99 DCHECK(json_string_.get()); |
99 } | 100 } |
100 | 101 |
101 DeviceCapabilitiesImpl::Data::~Data() {} | 102 DeviceCapabilitiesImpl::Data::~Data() {} |
102 | 103 |
103 DeviceCapabilitiesImpl::ValidatorInfo::ValidatorInfo(Validator* validator) | 104 DeviceCapabilitiesImpl::ValidatorInfo::ValidatorInfo(Validator* validator) |
104 : validator_(validator), task_runner_(base::ThreadTaskRunnerHandle::Get()) { | 105 : validator_(validator), task_runner_(base::ThreadTaskRunnerHandle::Get()) { |
105 DCHECK(validator_); | 106 DCHECK(validator_); |
106 DCHECK(task_runner_.get()); | 107 DCHECK(task_runner_.get()); |
107 } | 108 } |
108 | 109 |
109 DeviceCapabilitiesImpl::ValidatorInfo::~ValidatorInfo() { | 110 DeviceCapabilitiesImpl::ValidatorInfo::~ValidatorInfo() { |
110 // Check that ValidatorInfo is being destroyed on the same thread that it was | 111 // Check that ValidatorInfo is being destroyed on the same thread that it was |
111 // constructed on. | 112 // constructed on. |
112 DCHECK(task_runner_->BelongsToCurrentThread()); | 113 DCHECK(task_runner_->BelongsToCurrentThread()); |
113 } | 114 } |
114 | 115 |
115 void DeviceCapabilitiesImpl::ValidatorInfo::Validate( | 116 void DeviceCapabilitiesImpl::ValidatorInfo::Validate( |
116 const std::string& path, | 117 const std::string& path, |
117 scoped_ptr<base::Value> proposed_value) const { | 118 scoped_ptr<base::Value> proposed_value) const { |
118 // Check that we are running Validate on the same thread that ValidatorInfo | 119 // Check that we are running Validate on the same thread that ValidatorInfo |
119 // was constructed on. | 120 // was constructed on. |
120 DCHECK(task_runner_->BelongsToCurrentThread()); | 121 DCHECK(task_runner_->BelongsToCurrentThread()); |
121 validator_->Validate(path, proposed_value.Pass()); | 122 validator_->Validate(path, std::move(proposed_value)); |
122 } | 123 } |
123 | 124 |
124 DeviceCapabilitiesImpl::DeviceCapabilitiesImpl() | 125 DeviceCapabilitiesImpl::DeviceCapabilitiesImpl() |
125 : data_(CreateData()), | 126 : data_(CreateData()), |
126 task_runner_for_writes_(base::ThreadTaskRunnerHandle::Get()), | 127 task_runner_for_writes_(base::ThreadTaskRunnerHandle::Get()), |
127 observer_list_(new base::ObserverListThreadSafe<Observer>) { | 128 observer_list_(new base::ObserverListThreadSafe<Observer>) { |
128 DCHECK(task_runner_for_writes_.get()); | 129 DCHECK(task_runner_for_writes_.get()); |
129 } | 130 } |
130 | 131 |
131 DeviceCapabilitiesImpl::~DeviceCapabilitiesImpl() { | 132 DeviceCapabilitiesImpl::~DeviceCapabilitiesImpl() { |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 // Validator gets unregistered, the call to Validate will get skipped. | 232 // Validator gets unregistered, the call to Validate will get skipped. |
232 validator_it->second->task_runner()->PostTask( | 233 validator_it->second->task_runner()->PostTask( |
233 FROM_HERE, base::Bind(&ValidatorInfo::Validate, | 234 FROM_HERE, base::Bind(&ValidatorInfo::Validate, |
234 validator_it->second->AsWeakPtr(), path, | 235 validator_it->second->AsWeakPtr(), path, |
235 base::Passed(&proposed_value))); | 236 base::Passed(&proposed_value))); |
236 return; | 237 return; |
237 } | 238 } |
238 } | 239 } |
239 // Since we are done checking for a registered Validator at this point, we | 240 // Since we are done checking for a registered Validator at this point, we |
240 // can release the lock. All further member access will be for capabilities. | 241 // can release the lock. All further member access will be for capabilities. |
241 SetValidatedValue(path, proposed_value.Pass()); | 242 SetValidatedValue(path, std::move(proposed_value)); |
242 } | 243 } |
243 | 244 |
244 void DeviceCapabilitiesImpl::MergeDictionary( | 245 void DeviceCapabilitiesImpl::MergeDictionary( |
245 const base::DictionaryValue& dict_value) { | 246 const base::DictionaryValue& dict_value) { |
246 for (base::DictionaryValue::Iterator it(dict_value); !it.IsAtEnd(); | 247 for (base::DictionaryValue::Iterator it(dict_value); !it.IsAtEnd(); |
247 it.Advance()) { | 248 it.Advance()) { |
248 SetCapability(it.key(), it.value().CreateDeepCopy()); | 249 SetCapability(it.key(), it.value().CreateDeepCopy()); |
249 } | 250 } |
250 } | 251 } |
251 | 252 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 return; | 286 return; |
286 } | 287 } |
287 | 288 |
288 // In this sequence, we create a deep copy, modify the deep copy, and then | 289 // In this sequence, we create a deep copy, modify the deep copy, and then |
289 // do a pointer swap. We do this to have minimal time spent in the | 290 // do a pointer swap. We do this to have minimal time spent in the |
290 // data_lock_. If we were to lock and modify the capabilities | 291 // data_lock_. If we were to lock and modify the capabilities |
291 // dictionary directly, there may be expensive writes that block other | 292 // dictionary directly, there may be expensive writes that block other |
292 // threads. | 293 // threads. |
293 scoped_ptr<base::DictionaryValue> dictionary_deep_copy( | 294 scoped_ptr<base::DictionaryValue> dictionary_deep_copy( |
294 data_->dictionary().CreateDeepCopy()); | 295 data_->dictionary().CreateDeepCopy()); |
295 dictionary_deep_copy->Set(path, new_value.Pass()); | 296 dictionary_deep_copy->Set(path, std::move(new_value)); |
296 scoped_refptr<Data> new_data(CreateData(dictionary_deep_copy.Pass())); | 297 scoped_refptr<Data> new_data(CreateData(std::move(dictionary_deep_copy))); |
297 | 298 |
298 { | 299 { |
299 base::AutoLock auto_lock(data_lock_); | 300 base::AutoLock auto_lock(data_lock_); |
300 // Using swap instead of assignment operator here because it's a little | 301 // Using swap instead of assignment operator here because it's a little |
301 // faster. Avoids an extra call to AddRef()/Release(). | 302 // faster. Avoids an extra call to AddRef()/Release(). |
302 data_.swap(new_data); | 303 data_.swap(new_data); |
303 } | 304 } |
304 | 305 |
305 // Even though ObseverListThreadSafe notifications are always asynchronous | 306 // Even though ObseverListThreadSafe notifications are always asynchronous |
306 // (posts task even if to same thread), no locks should be held at this point | 307 // (posts task even if to same thread), no locks should be held at this point |
307 // in the code. This is just to be safe that no deadlocks occur if Observers | 308 // in the code. This is just to be safe that no deadlocks occur if Observers |
308 // call DeviceCapabilities methods in OnCapabilitiesChanged(). | 309 // call DeviceCapabilities methods in OnCapabilitiesChanged(). |
309 observer_list_->Notify(FROM_HERE, &Observer::OnCapabilitiesChanged, path); | 310 observer_list_->Notify(FROM_HERE, &Observer::OnCapabilitiesChanged, path); |
310 } | 311 } |
311 | 312 |
312 } // namespace chromecast | 313 } // namespace chromecast |
OLD | NEW |