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/mac/lib/rlz_value_store_mac.h" | 5 #include "rlz/mac/lib/rlz_value_store_mac.h" |
6 | 6 |
7 #include "base/mac/foundation_util.h" | 7 #include "base/mac/foundation_util.h" |
8 #include "base/file_path.h" | 8 #include "base/file_path.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/sys_string_conversions.h" | 10 #include "base/sys_string_conversions.h" |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
228 // directory of |lock_file| must exist. | 228 // directory of |lock_file| must exist. |
229 bool TryGetCrossProcessLock(NSString* lock_filename); | 229 bool TryGetCrossProcessLock(NSString* lock_filename); |
230 | 230 |
231 // Releases the lock. Should always be called, even if | 231 // Releases the lock. Should always be called, even if |
232 // TryGetCrossProcessLock() returns false. | 232 // TryGetCrossProcessLock() returns false. |
233 void ReleaseLock(); | 233 void ReleaseLock(); |
234 | 234 |
235 pthread_mutex_t recursive_lock_; | 235 pthread_mutex_t recursive_lock_; |
236 pthread_t locking_thread_; | 236 pthread_t locking_thread_; |
237 | 237 |
238 NSDistributedLock* file_lock_; | 238 int file_lock_; |
Scott Hess - ex-Googler
2012/08/15 00:44:38
ScopedFD?
Nico
2012/08/15 03:24:12
It needs to be closed while the mutex is still hel
Scott Hess - ex-Googler
2012/08/15 19:55:04
That's what reset() is for.
| |
239 } g_recursive_lock = { | 239 } g_recursive_lock = { |
240 // PTHREAD_RECURSIVE_MUTEX_INITIALIZER doesn't exist before 10.7 and is buggy | 240 // PTHREAD_RECURSIVE_MUTEX_INITIALIZER doesn't exist before 10.7 and is buggy |
241 // on 10.7 (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51906#c34), so emulate | 241 // on 10.7 (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51906#c34), so emulate |
242 // recursive locking with a normal non-recursive mutex. | 242 // recursive locking with a normal non-recursive mutex. |
243 PTHREAD_MUTEX_INITIALIZER | 243 PTHREAD_MUTEX_INITIALIZER |
244 }; | 244 }; |
245 | 245 |
246 bool RecursiveCrossProcessLock::TryGetCrossProcessLock( | 246 bool RecursiveCrossProcessLock::TryGetCrossProcessLock( |
247 NSString* lock_filename) { | 247 NSString* lock_filename) { |
248 bool just_got_lock = false; | 248 bool just_got_lock = false; |
(...skipping 11 matching lines...) Expand all Loading... | |
260 } | 260 } |
261 | 261 |
262 locking_thread_ = pthread_self(); | 262 locking_thread_ = pthread_self(); |
263 | 263 |
264 // Try to acquire file lock. | 264 // Try to acquire file lock. |
265 if (just_got_lock) { | 265 if (just_got_lock) { |
266 const int kMaxTimeoutMS = 5000; // Matches windows. | 266 const int kMaxTimeoutMS = 5000; // Matches windows. |
267 const int kSleepPerTryMS = 200; | 267 const int kSleepPerTryMS = 200; |
268 | 268 |
269 CHECK(!file_lock_); | 269 CHECK(!file_lock_); |
270 file_lock_ = [[NSDistributedLock alloc] initWithPath:lock_filename]; | 270 file_lock_ = open([lock_filename fileSystemRepresentation], O_CREAT); |
271 | 271 if (file_lock_ == -1) { |
272 BOOL got_file_lock = NO; | 272 file_lock_ = 0; |
Scott Hess - ex-Googler
2012/08/15 00:44:38
0 is a valid fd. Suggest using -1 for invalid, ju
Mark Mentovai
2012/08/15 00:50:54
But 0 is a valid FD. You should rewrite things to
Nico
2012/08/15 03:24:12
Done. (But in practice 0 is stdin, so in practice
Mark Mentovai
2012/08/15 13:36:28
Nico wrote:
| |
273 int elapsedMS = 0; | 273 return false; |
274 while (!(got_file_lock = [file_lock_ tryLock]) && | |
275 elapsedMS < kMaxTimeoutMS) { | |
276 usleep(kSleepPerTryMS * 1000); | |
277 elapsedMS += kSleepPerTryMS; | |
278 } | 274 } |
279 | 275 |
280 if (!got_file_lock) { | 276 int flock_result = -1; |
281 [file_lock_ release]; | 277 int elapsedMS = 0; |
Mark Mentovai
2012/08/15 00:50:54
elapsed_ms
Nico
2012/08/15 03:24:12
Done.
| |
282 file_lock_ = nil; | 278 while ((flock_result = flock(file_lock_, LOCK_EX | LOCK_NB)) == -1 && |
Scott Hess - ex-Googler
2012/08/15 00:44:38
errno == EWOULDBLOCK &&
Then you can lift the if(
Mark Mentovai
2012/08/15 00:50:54
HANDLE_EINTR
Nico
2012/08/15 03:24:12
Done.
| |
279 elapsedMS < kMaxTimeoutMS) { | |
280 if (errno == EWOULDBLOCK) { | |
281 usleep(kSleepPerTryMS * 1000); | |
282 elapsedMS += kSleepPerTryMS; | |
Scott Hess - ex-Googler
2012/08/15 00:44:38
usleep() could be interrupted by a signal, in whic
Nico
2012/08/15 03:24:12
Added HANDLE_EINTR here too.
Mark Mentovai
2012/08/15 13:36:28
HANDLE_EINTR doesn’t really help here because the
Nico
2012/08/15 14:52:50
Good (pathological) point! Removed it again.
Scott Hess - ex-Googler
2012/08/15 19:55:04
I think the POSIXy way is something like:
int e
Mark Mentovai
2012/08/15 20:18:39
shess wrote:
| |
283 } else { | |
284 close(file_lock_); | |
285 file_lock_ = 0; | |
286 return false; | |
287 } | |
288 } | |
289 | |
290 if (flock_result == -1) { | |
291 close(file_lock_); | |
Mark Mentovai
2012/08/15 00:50:54
This duplicates what’s in the loop. I think you on
Nico
2012/08/15 03:24:12
Done, together with shess's suggestion above.
| |
292 file_lock_ = 0; | |
283 return false; | 293 return false; |
284 } | 294 } |
285 return true; | 295 return true; |
286 } else { | 296 } else { |
287 return file_lock_ != nil; | 297 return file_lock_ != 0; |
288 } | 298 } |
289 } | 299 } |
290 | 300 |
291 void RecursiveCrossProcessLock::ReleaseLock() { | 301 void RecursiveCrossProcessLock::ReleaseLock() { |
292 if (file_lock_) { | 302 if (file_lock_) { |
293 [file_lock_ unlock]; | 303 flock(file_lock_, LOCK_UN); |
294 [file_lock_ release]; | 304 close(file_lock_); |
295 file_lock_ = nil; | 305 file_lock_ = 0; |
296 } | 306 } |
297 | 307 |
298 locking_thread_ = 0; | 308 locking_thread_ = 0; |
299 pthread_mutex_unlock(&recursive_lock_); | 309 pthread_mutex_unlock(&recursive_lock_); |
300 } | 310 } |
301 | 311 |
302 | 312 |
303 // This is set during test execution, to write RLZ files into a temporary | 313 // This is set during test execution, to write RLZ files into a temporary |
304 // directory instead of the user's Application Support folder. | 314 // directory instead of the user's Application Support folder. |
305 NSString* g_test_folder; | 315 NSString* g_test_folder; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
340 // Returns the path of the rlz plist store, also creates the parent directory | 350 // Returns the path of the rlz plist store, also creates the parent directory |
341 // path if it doesn't exist. | 351 // path if it doesn't exist. |
342 NSString* RlzPlistFilename() { | 352 NSString* RlzPlistFilename() { |
343 NSString* const kRlzFile = @"RlzStore.plist"; | 353 NSString* const kRlzFile = @"RlzStore.plist"; |
344 return [CreateRlzDirectory() stringByAppendingPathComponent:kRlzFile]; | 354 return [CreateRlzDirectory() stringByAppendingPathComponent:kRlzFile]; |
345 } | 355 } |
346 | 356 |
347 // Returns the path of the rlz lock file, also creates the parent directory | 357 // Returns the path of the rlz lock file, also creates the parent directory |
348 // path if it doesn't exist. | 358 // path if it doesn't exist. |
349 NSString* RlzLockFilename() { | 359 NSString* RlzLockFilename() { |
350 NSString* const kRlzFile = @"lockfile"; | 360 NSString* const kRlzFile = @"flockfile"; |
351 return [CreateRlzDirectory() stringByAppendingPathComponent:kRlzFile]; | 361 return [CreateRlzDirectory() stringByAppendingPathComponent:kRlzFile]; |
352 } | 362 } |
353 | 363 |
354 } // namespace | 364 } // namespace |
355 | 365 |
356 ScopedRlzValueStoreLock::ScopedRlzValueStoreLock() { | 366 ScopedRlzValueStoreLock::ScopedRlzValueStoreLock() { |
357 bool got_distributed_lock = | 367 bool got_distributed_lock = |
358 g_recursive_lock.TryGetCrossProcessLock(RlzLockFilename()); | 368 g_recursive_lock.TryGetCrossProcessLock(RlzLockFilename()); |
359 // At this point, we hold the in-process lock, no matter the value of | 369 // At this point, we hold the in-process lock, no matter the value of |
360 // |got_distributed_lock|. | 370 // |got_distributed_lock|. |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
438 } else { | 448 } else { |
439 // Not Unsafe on OS X. | 449 // Not Unsafe on OS X. |
440 g_test_folder = | 450 g_test_folder = |
441 [[NSString alloc] initWithUTF8String:directory.AsUTF8Unsafe().c_str()]; | 451 [[NSString alloc] initWithUTF8String:directory.AsUTF8Unsafe().c_str()]; |
442 } | 452 } |
443 } | 453 } |
444 | 454 |
445 } // namespace testing | 455 } // namespace testing |
446 | 456 |
447 } // namespace rlz_lib | 457 } // namespace rlz_lib |
OLD | NEW |