Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(585)

Side by Side Diff: rlz/mac/lib/rlz_value_store_mac.mm

Issue 10823329: rlz/mac: Make sure a crashing process doesn't leave a stale lockfile behind. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« rlz/lib/rlz_lib_test.cc ('K') | « rlz/lib/rlz_lib_test.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« rlz/lib/rlz_lib_test.cc ('K') | « rlz/lib/rlz_lib_test.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698