OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "rlz/chromeos/lib/rlz_value_store_chromeos.h" | 5 #include "rlz/chromeos/lib/rlz_value_store_chromeos.h" |
6 | 6 |
7 #include "base/file_path.h" | |
8 #include "base/file_util.h" | 7 #include "base/file_util.h" |
8 #include "base/files/important_file_writer.h" | |
9 #include "base/json/json_file_value_serializer.h" | |
10 #include "base/json/json_string_value_serializer.h" | |
9 #include "base/logging.h" | 11 #include "base/logging.h" |
10 #include "base/memory/singleton.h" | |
11 #include "base/prefs/json_pref_store.h" | |
12 #include "base/sequenced_task_runner.h" | 12 #include "base/sequenced_task_runner.h" |
13 #include "base/string_number_conversions.h" | 13 #include "base/string_number_conversions.h" |
14 #include "base/values.h" | 14 #include "base/values.h" |
15 #include "rlz/lib/lib_values.h" | 15 #include "rlz/lib/lib_values.h" |
16 #include "rlz/lib/recursive_lock.h" | 16 #include "rlz/lib/recursive_cross_process_lock_posix.h" |
17 #include "rlz/lib/rlz_lib.h" | 17 #include "rlz/lib/rlz_lib.h" |
18 | 18 |
19 namespace rlz_lib { | 19 namespace rlz_lib { |
20 | 20 |
21 namespace { | 21 namespace { |
22 | 22 |
23 // Product names. | 23 // Product names. |
24 const char kProductChrome[] = "chrome"; | 24 const char kProductChrome[] = "chrome"; |
25 const char kProductOther[] = "other"; | 25 const char kProductOther[] = "other"; |
26 | 26 |
27 // Key names. | 27 // Key names. |
28 const char kPingTimeKey[] = "ping_time"; | 28 const char kPingTimeKey[] = "ping_time"; |
29 const char kAccessPointKey[] = "access_points"; | 29 const char kAccessPointKey[] = "access_points"; |
30 const char kProductEventKey[] = "product_events"; | 30 const char kProductEventKey[] = "product_events"; |
31 const char kStatefulEventKey[] = "stateful_events"; | 31 const char kStatefulEventKey[] = "stateful_events"; |
32 | 32 |
33 // Brand name used when there is no supplementary brand name. | 33 // Brand name used when there is no supplementary brand name. |
34 const char kNoSupplementaryBrand[] = "_"; | 34 const char kNoSupplementaryBrand[] = "_"; |
35 | 35 |
36 // RLZ store filename. | 36 // RLZ store filename. |
37 const FilePath::CharType kRLZDataFileName[] = FILE_PATH_LITERAL("RLZ Data"); | 37 const FilePath::CharType kRLZDataFileName[] = FILE_PATH_LITERAL("RLZ Data"); |
38 | 38 |
39 // RLZ store lock filename | |
40 const FilePath::CharType kRLZLockFileName[] = | |
41 FILE_PATH_LITERAL("RLZ Data.lock"); | |
42 | |
39 // RLZ store path for testing. | 43 // RLZ store path for testing. |
40 FilePath g_testing_rlz_store_path_; | 44 FilePath g_testing_rlz_store_path_; |
41 | 45 |
42 // Returns file path of the RLZ storage. | 46 // Returns file path of the RLZ storage. |
43 FilePath GetRlzStorePath() { | 47 FilePath GetRlzStorePath() { |
44 return g_testing_rlz_store_path_.empty() ? | 48 return g_testing_rlz_store_path_.empty() ? |
45 file_util::GetHomeDir().Append(kRLZDataFileName) : | 49 file_util::GetHomeDir().Append(kRLZDataFileName) : |
46 g_testing_rlz_store_path_.Append(kRLZDataFileName); | 50 g_testing_rlz_store_path_.Append(kRLZDataFileName); |
47 } | 51 } |
48 | 52 |
53 // Returns file path of the RLZ storage lock file. | |
54 FilePath GetRlzStoreLockPath() { | |
55 return g_testing_rlz_store_path_.empty() ? | |
56 file_util::GetHomeDir().Append(kRLZLockFileName) : | |
57 g_testing_rlz_store_path_.Append(kRLZLockFileName); | |
58 } | |
59 | |
49 // Returns the dictionary key for storing access point-related prefs. | 60 // Returns the dictionary key for storing access point-related prefs. |
50 std::string GetKeyName(std::string key, AccessPoint access_point) { | 61 std::string GetKeyName(std::string key, AccessPoint access_point) { |
51 std::string brand = SupplementaryBranding::GetBrand(); | 62 std::string brand = SupplementaryBranding::GetBrand(); |
52 if (brand.empty()) | 63 if (brand.empty()) |
53 brand = kNoSupplementaryBrand; | 64 brand = kNoSupplementaryBrand; |
54 return key + "." + GetAccessPointName(access_point) + "." + brand; | 65 return key + "." + GetAccessPointName(access_point) + "." + brand; |
55 } | 66 } |
56 | 67 |
57 // Returns the dictionary key for storing product-related prefs. | 68 // Returns the dictionary key for storing product-related prefs. |
58 std::string GetKeyName(std::string key, Product product) { | 69 std::string GetKeyName(std::string key, Product product) { |
59 std::string brand = SupplementaryBranding::GetBrand(); | 70 std::string brand = SupplementaryBranding::GetBrand(); |
60 if (brand.empty()) | 71 if (brand.empty()) |
61 brand = kNoSupplementaryBrand; | 72 brand = kNoSupplementaryBrand; |
62 return key + "." + GetProductName(product) + "." + brand; | 73 return key + "." + GetProductName(product) + "." + brand; |
63 } | 74 } |
64 | 75 |
65 } // namespace | 76 } // namespace |
66 | 77 |
67 // static | 78 RlzValueStoreChromeOS::RlzValueStoreChromeOS(const FilePath& store_path) |
68 base::SequencedTaskRunner* RlzValueStoreChromeOS::io_task_runner_ = NULL; | 79 : rlz_store_(new base::DictionaryValue), |
69 | 80 store_path_(store_path), |
70 // static | 81 read_only_(true) { |
71 bool RlzValueStoreChromeOS::created_; | 82 DCHECK(CalledOnValidThread()); |
Roger Tawa OOO till Jul 10th
2012/11/26 19:16:51
why call CalledOnValidThread() in ctor?
Ivan Korotkov
2012/11/27 11:37:25
Right, removed.
| |
72 | 83 ReadStore(); |
73 // static | |
74 RlzValueStoreChromeOS* RlzValueStoreChromeOS::GetInstance() { | |
75 return Singleton<RlzValueStoreChromeOS>::get(); | |
76 } | |
77 | |
78 // static | |
79 void RlzValueStoreChromeOS::SetIOTaskRunner( | |
80 base::SequencedTaskRunner* io_task_runner) { | |
81 io_task_runner_ = io_task_runner; | |
82 // Make sure |io_task_runner_| lives until constructor is called. | |
83 io_task_runner_->AddRef(); | |
84 } | |
85 | |
86 // static | |
87 void RlzValueStoreChromeOS::ResetForTesting() { | |
88 // Make sure we don't create an instance if it didn't exist. | |
89 if (created_) | |
90 GetInstance()->ReadPrefs(); | |
91 } | |
92 | |
93 // static | |
94 void RlzValueStoreChromeOS::Cleanup() { | |
95 if (created_) | |
96 GetInstance()->rlz_store_ = NULL; | |
97 } | |
98 | |
99 RlzValueStoreChromeOS::RlzValueStoreChromeOS() { | |
100 ReadPrefs(); | |
101 created_ = true; | |
102 } | 84 } |
103 | 85 |
104 RlzValueStoreChromeOS::~RlzValueStoreChromeOS() { | 86 RlzValueStoreChromeOS::~RlzValueStoreChromeOS() { |
87 DCHECK(CalledOnValidThread()); | |
Roger Tawa OOO till Jul 10th
2012/11/26 19:16:51
the base class dtor already calls CalledOnValidThr
Ivan Korotkov
2012/11/27 11:37:25
Removed.
| |
88 WriteStore(); | |
105 } | 89 } |
106 | 90 |
107 bool RlzValueStoreChromeOS::HasAccess(AccessType type) { | 91 bool RlzValueStoreChromeOS::HasAccess(AccessType type) { |
108 return type == kReadAccess || !rlz_store_->ReadOnly(); | 92 DCHECK(CalledOnValidThread()); |
93 return type == kReadAccess || !read_only_; | |
109 } | 94 } |
110 | 95 |
111 bool RlzValueStoreChromeOS::WritePingTime(Product product, int64 time) { | 96 bool RlzValueStoreChromeOS::WritePingTime(Product product, int64 time) { |
112 std::string value = base::Int64ToString(time); | 97 DCHECK(CalledOnValidThread()); |
113 rlz_store_->SetValue(GetKeyName(kPingTimeKey, product), | 98 rlz_store_->SetString(GetKeyName(kPingTimeKey, product), |
114 base::Value::CreateStringValue(value)); | 99 base::Int64ToString(time)); |
Roger Tawa OOO till Jul 10th
2012/11/26 19:16:51
one extra space.
Ivan Korotkov
2012/11/27 11:37:25
Done.
| |
115 return true; | 100 return true; |
116 } | 101 } |
117 | 102 |
118 bool RlzValueStoreChromeOS::ReadPingTime(Product product, int64* time) { | 103 bool RlzValueStoreChromeOS::ReadPingTime(Product product, int64* time) { |
119 const base::Value* value = NULL; | 104 DCHECK(CalledOnValidThread()); |
120 rlz_store_->GetValue(GetKeyName(kPingTimeKey, product), &value); | 105 std::string ping_time; |
121 std::string s_value; | 106 return rlz_store_->GetString(GetKeyName(kPingTimeKey, product), &ping_time) && |
122 return value && value->GetAsString(&s_value) && | 107 base::StringToInt64(ping_time, time); |
123 base::StringToInt64(s_value, time); | |
124 } | 108 } |
125 | 109 |
126 bool RlzValueStoreChromeOS::ClearPingTime(Product product) { | 110 bool RlzValueStoreChromeOS::ClearPingTime(Product product) { |
127 rlz_store_->RemoveValue(GetKeyName(kPingTimeKey, product)); | 111 DCHECK(CalledOnValidThread()); |
112 rlz_store_->Remove(GetKeyName(kPingTimeKey, product), NULL); | |
128 return true; | 113 return true; |
129 } | 114 } |
130 | 115 |
131 bool RlzValueStoreChromeOS::WriteAccessPointRlz(AccessPoint access_point, | 116 bool RlzValueStoreChromeOS::WriteAccessPointRlz(AccessPoint access_point, |
132 const char* new_rlz) { | 117 const char* new_rlz) { |
133 rlz_store_->SetValue( | 118 DCHECK(CalledOnValidThread()); |
134 GetKeyName(kAccessPointKey, access_point), | 119 rlz_store_->SetString( |
135 base::Value::CreateStringValue(new_rlz)); | 120 GetKeyName(kAccessPointKey, access_point), new_rlz); |
136 return true; | 121 return true; |
137 } | 122 } |
138 | 123 |
139 bool RlzValueStoreChromeOS::ReadAccessPointRlz(AccessPoint access_point, | 124 bool RlzValueStoreChromeOS::ReadAccessPointRlz(AccessPoint access_point, |
140 char* rlz, | 125 char* rlz, |
141 size_t rlz_size) { | 126 size_t rlz_size) { |
142 const base::Value* value = NULL; | 127 DCHECK(CalledOnValidThread()); |
143 rlz_store_->GetValue( | 128 std::string rlz_value; |
144 GetKeyName(kAccessPointKey, access_point), &value); | 129 rlz_store_->GetString(GetKeyName(kAccessPointKey, access_point), &rlz_value); |
145 std::string s_value; | 130 if (rlz_value.size() < rlz_size) { |
146 if (value) | 131 strncpy(rlz, rlz_value.c_str(), rlz_size); |
147 value->GetAsString(&s_value); | |
148 if (s_value.size() < rlz_size) { | |
149 strncpy(rlz, s_value.c_str(), rlz_size); | |
150 return true; | 132 return true; |
151 } | 133 } |
152 if (rlz_size > 0) | 134 if (rlz_size > 0) |
153 *rlz = '\0'; | 135 *rlz = '\0'; |
154 return false; | 136 return false; |
155 } | 137 } |
156 | 138 |
157 bool RlzValueStoreChromeOS::ClearAccessPointRlz(AccessPoint access_point) { | 139 bool RlzValueStoreChromeOS::ClearAccessPointRlz(AccessPoint access_point) { |
158 rlz_store_->RemoveValue( | 140 DCHECK(CalledOnValidThread()); |
159 GetKeyName(kAccessPointKey, access_point)); | 141 rlz_store_->Remove(GetKeyName(kAccessPointKey, access_point), NULL); |
160 return true; | 142 return true; |
161 } | 143 } |
162 | 144 |
163 bool RlzValueStoreChromeOS::AddProductEvent(Product product, | 145 bool RlzValueStoreChromeOS::AddProductEvent(Product product, |
164 const char* event_rlz) { | 146 const char* event_rlz) { |
147 DCHECK(CalledOnValidThread()); | |
165 return AddValueToList(GetKeyName(kProductEventKey, product), | 148 return AddValueToList(GetKeyName(kProductEventKey, product), |
166 base::Value::CreateStringValue(event_rlz)); | 149 base::Value::CreateStringValue(event_rlz)); |
167 } | 150 } |
168 | 151 |
169 bool RlzValueStoreChromeOS::ReadProductEvents( | 152 bool RlzValueStoreChromeOS::ReadProductEvents( |
170 Product product, | 153 Product product, |
171 std::vector<std::string>* events) { | 154 std::vector<std::string>* events) { |
172 base::ListValue* events_list = GetList(GetKeyName(kProductEventKey, product)); | 155 DCHECK(CalledOnValidThread()); |
173 if (!events_list) | 156 base::ListValue* events_list = NULL; ; |
157 if (!rlz_store_->GetList(GetKeyName(kProductEventKey, product), &events_list)) | |
174 return false; | 158 return false; |
175 events->clear(); | 159 events->clear(); |
176 for (size_t i = 0; i < events_list->GetSize(); ++i) { | 160 for (size_t i = 0; i < events_list->GetSize(); ++i) { |
177 std::string event; | 161 std::string event; |
178 if (events_list->GetString(i, &event)) | 162 if (events_list->GetString(i, &event)) |
179 events->push_back(event); | 163 events->push_back(event); |
180 } | 164 } |
181 return true; | 165 return true; |
182 } | 166 } |
183 | 167 |
184 bool RlzValueStoreChromeOS::ClearProductEvent(Product product, | 168 bool RlzValueStoreChromeOS::ClearProductEvent(Product product, |
185 const char* event_rlz) { | 169 const char* event_rlz) { |
170 DCHECK(CalledOnValidThread()); | |
186 base::StringValue event_value(event_rlz); | 171 base::StringValue event_value(event_rlz); |
187 return RemoveValueFromList(GetKeyName(kProductEventKey, product), | 172 return RemoveValueFromList(GetKeyName(kProductEventKey, product), |
188 event_value); | 173 event_value); |
189 } | 174 } |
190 | 175 |
191 bool RlzValueStoreChromeOS::ClearAllProductEvents(Product product) { | 176 bool RlzValueStoreChromeOS::ClearAllProductEvents(Product product) { |
192 rlz_store_->RemoveValue(GetKeyName(kProductEventKey, product)); | 177 DCHECK(CalledOnValidThread()); |
178 rlz_store_->Remove(GetKeyName(kProductEventKey, product), NULL); | |
193 return true; | 179 return true; |
194 } | 180 } |
195 | 181 |
196 bool RlzValueStoreChromeOS::AddStatefulEvent(Product product, | 182 bool RlzValueStoreChromeOS::AddStatefulEvent(Product product, |
197 const char* event_rlz) { | 183 const char* event_rlz) { |
184 DCHECK(CalledOnValidThread()); | |
198 return AddValueToList(GetKeyName(kStatefulEventKey, product), | 185 return AddValueToList(GetKeyName(kStatefulEventKey, product), |
199 base::Value::CreateStringValue(event_rlz)); | 186 base::Value::CreateStringValue(event_rlz)); |
200 } | 187 } |
201 | 188 |
202 bool RlzValueStoreChromeOS::IsStatefulEvent(Product product, | 189 bool RlzValueStoreChromeOS::IsStatefulEvent(Product product, |
203 const char* event_rlz) { | 190 const char* event_rlz) { |
204 base::ListValue* events_list = | 191 DCHECK(CalledOnValidThread()); |
205 GetList(GetKeyName(kStatefulEventKey, product)); | |
206 base::StringValue event_value(event_rlz); | 192 base::StringValue event_value(event_rlz); |
207 return events_list && events_list->Find(event_value) != events_list->end(); | 193 base::ListValue* events_list = NULL; |
194 return rlz_store_->GetList(GetKeyName(kStatefulEventKey, product), | |
195 &events_list) && | |
196 events_list->Find(event_value) != events_list->end(); | |
208 } | 197 } |
209 | 198 |
210 bool RlzValueStoreChromeOS::ClearAllStatefulEvents(Product product) { | 199 bool RlzValueStoreChromeOS::ClearAllStatefulEvents(Product product) { |
211 rlz_store_->RemoveValue(GetKeyName(kStatefulEventKey, product)); | 200 DCHECK(CalledOnValidThread()); |
201 rlz_store_->Remove(GetKeyName(kStatefulEventKey, product), NULL); | |
212 return true; | 202 return true; |
213 } | 203 } |
214 | 204 |
215 void RlzValueStoreChromeOS::CollectGarbage() { | 205 void RlzValueStoreChromeOS::CollectGarbage() { |
206 DCHECK(CalledOnValidThread()); | |
216 NOTIMPLEMENTED(); | 207 NOTIMPLEMENTED(); |
217 } | 208 } |
218 | 209 |
219 void RlzValueStoreChromeOS::ReadPrefs() { | 210 void RlzValueStoreChromeOS::ReadStore() { |
220 DCHECK(io_task_runner_) | 211 int error_code = 0; |
221 << "Calling GetInstance or ResetForTesting before SetIOTaskRunner?"; | 212 std::string error_msg; |
222 rlz_store_ = new JsonPrefStore(GetRlzStorePath(), io_task_runner_); | 213 JSONFileValueSerializer serializer(store_path_); |
223 rlz_store_->ReadPrefs(); | 214 scoped_ptr<base::Value> value( |
224 switch (rlz_store_->GetReadError()) { | 215 serializer.Deserialize(&error_code, &error_msg)); |
225 case PersistentPrefStore::PREF_READ_ERROR_NONE: | 216 switch (error_code) { |
226 case PersistentPrefStore::PREF_READ_ERROR_NO_FILE: | 217 case JSONFileValueSerializer::JSON_NO_SUCH_FILE: |
218 read_only_ = false; | |
Roger Tawa OOO till Jul 10th
2012/11/26 19:16:51
why set read-only to false here?
Ivan Korotkov
2012/11/27 11:37:25
NO_SUCH_FILE means RLZ store hasn't been created y
| |
219 break; | |
220 case JSONFileValueSerializer::JSON_NO_ERROR: | |
221 read_only_ = false; | |
222 rlz_store_.reset(static_cast<base::DictionaryValue*>(value.release())); | |
227 break; | 223 break; |
228 default: | 224 default: |
229 LOG(ERROR) << "Error read RLZ store: " << rlz_store_->GetReadError(); | 225 LOG(ERROR) << "Error reading RLZ store: " << error_msg; |
230 } | 226 } |
231 // Restore refcount modified by SetIOTaskRunner(). | |
232 io_task_runner_->Release(); | |
233 io_task_runner_ = NULL; | |
234 } | 227 } |
235 | 228 |
236 base::ListValue* RlzValueStoreChromeOS::GetList(std::string list_name) { | 229 void RlzValueStoreChromeOS::WriteStore() { |
237 base::Value* list_value = NULL; | 230 std::string json_data; |
238 rlz_store_->GetMutableValue(list_name, &list_value); | 231 JSONStringValueSerializer serializer(&json_data); |
239 base::ListValue* list = NULL; | 232 serializer.set_pretty_print(true); |
240 if (!list_value || !list_value->GetAsList(&list)) | 233 scoped_ptr<DictionaryValue> copy(rlz_store_->DeepCopyWithoutEmptyChildren()); |
241 return NULL; | 234 if (!serializer.Serialize(*copy.get())) { |
242 return list; | 235 LOG(ERROR) << "Failed to serialize RLZ data"; |
236 NOTREACHED(); | |
237 return; | |
238 } | |
239 if (!base::ImportantFileWriter::WriteToDisk(store_path_, json_data)) | |
240 LOG(ERROR) << "Error writing RLZ store"; | |
243 } | 241 } |
244 | 242 |
245 bool RlzValueStoreChromeOS::AddValueToList(std::string list_name, | 243 bool RlzValueStoreChromeOS::AddValueToList(std::string list_name, |
246 base::Value* value) { | 244 base::Value* value) { |
247 base::ListValue* list = GetList(list_name); | 245 base::ListValue* list_value = NULL; |
248 if (!list) { | 246 if (!rlz_store_->GetList(list_name, &list_value)) { |
249 list = new base::ListValue; | 247 list_value = new base::ListValue; |
250 rlz_store_->SetValue(list_name, list); | 248 rlz_store_->Set(list_name, list_value); |
251 } | 249 } |
252 if (list->AppendIfNotPresent(value)) | 250 list_value->AppendIfNotPresent(value); |
253 rlz_store_->ReportValueChanged(list_name); | |
254 return true; | 251 return true; |
255 } | 252 } |
256 | 253 |
257 bool RlzValueStoreChromeOS::RemoveValueFromList(std::string list_name, | 254 bool RlzValueStoreChromeOS::RemoveValueFromList(std::string list_name, |
258 const base::Value& value) { | 255 const base::Value& value) { |
259 base::ListValue* list = GetList(list_name); | 256 base::ListValue* list_value = NULL; |
260 if (!list) | 257 if (!rlz_store_->GetList(list_name, &list_value)) |
261 return false; | 258 return false; |
262 rlz_store_->MarkNeedsEmptyValue(list_name); | 259 // rlz_store_->MarkNeedsEmptyValue(list_name); |
Roger Tawa OOO till Jul 10th
2012/11/26 19:16:51
remove line?
Ivan Korotkov
2012/11/27 11:37:25
Done.
| |
263 size_t index; | 260 size_t index; |
264 if (list->Remove(value, &index)) | 261 list_value->Remove(value, &index); |
265 rlz_store_->ReportValueChanged(list_name); | |
266 return true; | 262 return true; |
267 } | 263 } |
268 | 264 |
265 namespace { | |
269 | 266 |
270 ScopedRlzValueStoreLock::ScopedRlzValueStoreLock() | 267 // RlzValueStoreChromeOS keeps its data in memory and only writes it to disk |
271 : store_(RlzValueStoreChromeOS::GetInstance()) { | 268 // when ScopedRlzValueStoreLock goes out of scope. Hence, if several |
269 // ScopedRlzValueStoreLocks are nested, they all need to use the same store | |
270 // object. | |
271 | |
272 RecursiveCrossProcessLock g_recursive_lock = | |
273 RECURSIVE_CROSS_PROCESS_LOCK_INITIALIZER; | |
274 | |
275 // This counts the nesting depth of |ScopedRlzValueStoreLock|. | |
276 int g_lock_depth = 0; | |
277 | |
278 // This is the shared store object. Non-|NULL| only when |g_lock_depth > 0|. | |
279 RlzValueStoreChromeOS* g_store = NULL; | |
280 | |
281 } // namespace | |
282 | |
283 ScopedRlzValueStoreLock::ScopedRlzValueStoreLock() { | |
284 bool got_cross_process_lock = | |
285 g_recursive_lock.TryGetCrossProcessLock(GetRlzStoreLockPath()); | |
286 // At this point, we hold the in-process lock, no matter the value of | |
287 // |got_cross_process_lock|. | |
288 | |
289 ++g_lock_depth; | |
290 if (!got_cross_process_lock) { | |
291 // Acquiring cross-process lock failed, so simply return here. | |
292 // In-process lock will be released in dtor. | |
293 DCHECK(!g_store); | |
Roger Tawa OOO till Jul 10th
2012/11/26 19:16:51
Maybe add DCHECK(g_lock_depth==1)? Does not happe
Ivan Korotkov
2012/11/27 11:37:25
See my comment in Lock
| |
294 return; | |
295 } | |
296 | |
297 if (g_lock_depth > 1) { | |
298 // Reuse the already existing store object. | |
299 DCHECK(g_store); | |
300 store_.reset(g_store); | |
301 return; | |
302 } | |
303 | |
304 // This is the topmost lock, create a new store object. | |
305 DCHECK(!g_store); | |
306 g_store = new RlzValueStoreChromeOS(GetRlzStorePath()); | |
307 store_.reset(g_store); | |
272 } | 308 } |
273 | 309 |
274 ScopedRlzValueStoreLock::~ScopedRlzValueStoreLock() { | 310 ScopedRlzValueStoreLock::~ScopedRlzValueStoreLock() { |
311 --g_lock_depth; | |
312 DCHECK(g_lock_depth >= 0); | |
313 | |
314 if (g_lock_depth > 0) { | |
315 // Other locks are still using store_, so don't free it yet. | |
316 ignore_result(store_.release()); | |
317 return; | |
318 } | |
319 | |
320 g_store = NULL; | |
321 | |
322 g_recursive_lock.ReleaseLock(); | |
275 } | 323 } |
276 | 324 |
277 RlzValueStore* ScopedRlzValueStoreLock::GetStore() { | 325 RlzValueStore* ScopedRlzValueStoreLock::GetStore() { |
278 return store_; | 326 return store_.get(); |
279 } | 327 } |
280 | 328 |
281 namespace testing { | 329 namespace testing { |
282 | 330 |
283 void SetRlzStoreDirectory(const FilePath& directory) { | 331 void SetRlzStoreDirectory(const FilePath& directory) { |
284 g_testing_rlz_store_path_ = directory; | 332 g_testing_rlz_store_path_ = directory; |
285 } | 333 } |
286 | 334 |
335 std::string RlzStoreFilenameStr() { | |
336 return GetRlzStorePath().value(); | |
337 } | |
338 | |
287 } // namespace testing | 339 } // namespace testing |
288 | 340 |
289 } // namespace rlz_lib | 341 } // namespace rlz_lib |
OLD | NEW |