summaryrefslogtreecommitdiffstats
path: root/rlz/lib/recursive_cross_process_lock_posix.cc
diff options
context:
space:
mode:
authorivankr@chromium.org <ivankr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-29 14:00:12 +0000
committerivankr@chromium.org <ivankr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-29 14:00:12 +0000
commit95b42e2745a2380a16112a059bd0e842d81f0c0a (patch)
tree8715285e587b94807bcc70cf135d99bdbec662fb /rlz/lib/recursive_cross_process_lock_posix.cc
parent1b14a45ac508a066cc3c060dd37327c3a13a6fda (diff)
downloadchromium_src-95b42e2745a2380a16112a059bd0e842d81f0c0a.zip
chromium_src-95b42e2745a2380a16112a059bd0e842d81f0c0a.tar.gz
chromium_src-95b42e2745a2380a16112a059bd0e842d81f0c0a.tar.bz2
[cros] RlzValueStore made protected by a cross-process lock and not persisted over browser lifetime (like on Mac).
*) Moved RecursiveCrossProcessLock out of .mm file to a common _posix file. *) Added static method to ImportantFileWriter that does blocking write on the current thread. *) Dedicated RLZ thread gone, replaced back with shutdown-blocking worker pool. BUG=157348,62328 Review URL: https://chromiumcodereview.appspot.com/11308196 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@170179 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'rlz/lib/recursive_cross_process_lock_posix.cc')
-rw-r--r--rlz/lib/recursive_cross_process_lock_posix.cc81
1 files changed, 81 insertions, 0 deletions
diff --git a/rlz/lib/recursive_cross_process_lock_posix.cc b/rlz/lib/recursive_cross_process_lock_posix.cc
new file mode 100644
index 0000000..071bf8c
--- /dev/null
+++ b/rlz/lib/recursive_cross_process_lock_posix.cc
@@ -0,0 +1,81 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "rlz/lib/recursive_cross_process_lock_posix.h"
+
+#include <sys/file.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "base/file_path.h"
+#include "base/logging.h"
+#include "base/posix/eintr_wrapper.h"
+
+namespace rlz_lib {
+
+bool RecursiveCrossProcessLock::TryGetCrossProcessLock(
+ const FilePath& lock_filename) {
+ bool just_got_lock = false;
+
+ // Emulate a recursive mutex with a non-recursive one.
+ if (pthread_mutex_trylock(&recursive_lock_) == EBUSY) {
+ if (pthread_equal(pthread_self(), locking_thread_) == 0) {
+ // Some other thread has the lock, wait for it.
+ pthread_mutex_lock(&recursive_lock_);
+ CHECK(locking_thread_ == 0);
+ just_got_lock = true;
+ }
+ } else {
+ just_got_lock = true;
+ }
+
+ locking_thread_ = pthread_self();
+
+ // Try to acquire file lock.
+ if (just_got_lock) {
+ const int kMaxTimeoutMS = 5000; // Matches Windows.
+ const int kSleepPerTryMS = 200;
+
+ CHECK(file_lock_ == -1);
+ file_lock_ = open(lock_filename.value().c_str(), O_RDWR | O_CREAT, 0666);
+ if (file_lock_ == -1) {
+ perror("open");
+ return false;
+ }
+
+ int flock_result = -1;
+ int elapsed_ms = 0;
+ while ((flock_result =
+ HANDLE_EINTR(flock(file_lock_, LOCK_EX | LOCK_NB))) == -1 &&
+ errno == EWOULDBLOCK &&
+ elapsed_ms < kMaxTimeoutMS) {
+ usleep(kSleepPerTryMS * 1000);
+ elapsed_ms += kSleepPerTryMS;
+ }
+
+ if (flock_result == -1) {
+ perror("flock");
+ ignore_result(HANDLE_EINTR(close(file_lock_)));
+ file_lock_ = -1;
+ return false;
+ }
+ return true;
+ } else {
+ return file_lock_ != -1;
+ }
+}
+
+void RecursiveCrossProcessLock::ReleaseLock() {
+ if (file_lock_ != -1) {
+ ignore_result(HANDLE_EINTR(flock(file_lock_, LOCK_UN)));
+ ignore_result(HANDLE_EINTR(close(file_lock_)));
+ file_lock_ = -1;
+ }
+
+ locking_thread_ = 0;
+ pthread_mutex_unlock(&recursive_lock_);
+}
+
+} // namespace rlz_lib