Commit 457bb54e authored by Adam Norberg's avatar Adam Norberg Committed by Commit Bot

Refactor prefs_mac to use ScopedMachReceiveRight.

This follows up on CL feedback from Robert Sesek on
https://chromium-review.googlesource.com/c/chromium/src/+/2453800
which arrived after I already submitted the CL.

Bug: 1135692
Change-Id: I868fbfe366a08d27263a313afa698bdcebe9c151
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2508325Reviewed-by: default avatarRobert Sesek <rsesek@chromium.org>
Reviewed-by: default avatarJoshua Pawlicki <waffles@chromium.org>
Commit-Queue: Adam Norberg <norberg@google.com>
Cr-Commit-Position: refs/heads/master@{#826896}
parent af0e1367
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/logging.h" #include "base/logging.h"
#include "base/mac/mach_logging.h" #include "base/mac/mach_logging.h"
#include "base/mac/scoped_mach_port.h"
#include "base/threading/platform_thread.h" #include "base/threading/platform_thread.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "chrome/updater/updater_version.h" #include "chrome/updater/updater_version.h"
...@@ -30,13 +31,13 @@ constexpr base::TimeDelta kPrefsLockPollingInterval = ...@@ -30,13 +31,13 @@ constexpr base::TimeDelta kPrefsLockPollingInterval =
// since "permission denied" typically means the service receive rights have // since "permission denied" typically means the service receive rights have
// already been assigned. // already been assigned.
// //
// Returns a mach_port_t representing the receive right if the right was // Returns the receive right if the right was successfully acquired. If the
// successfully acquired. If the right cannot be acquired for any reason, // right cannot be acquired for any reason, returns an invalid right instead.
// returns MACH_PORT_NULL instead. base::mac::ScopedMachReceiveRight TryAcquireReceive(const char* service_name) {
mach_port_t TryAcquireReceive(const char* service_name) { base::mac::ScopedMachReceiveRight target_right;
mach_port_t target_port = MACH_PORT_NULL; kern_return_t check_in_result = bootstrap_check_in(
kern_return_t check_in_result = bootstrap_port, service_name,
bootstrap_check_in(bootstrap_port, service_name, &target_port); base::mac::ScopedMachReceiveRight::Receiver(target_right).get());
if (check_in_result != KERN_SUCCESS) { if (check_in_result != KERN_SUCCESS) {
// Log error reports for all errors other than BOOTSTRAP_NOT_PRIVILEGED. // Log error reports for all errors other than BOOTSTRAP_NOT_PRIVILEGED.
// BOOTSTRAP_NOT_PRIVILEGED is not logged because it just means that another // BOOTSTRAP_NOT_PRIVILEGED is not logged because it just means that another
...@@ -49,9 +50,9 @@ mach_port_t TryAcquireReceive(const char* service_name) { ...@@ -49,9 +50,9 @@ mach_port_t TryAcquireReceive(const char* service_name) {
BOOTSTRAP_VLOG(2, check_in_result) BOOTSTRAP_VLOG(2, check_in_result)
<< "Prefs lock already held: " << kPrefsLockMachServiceName; << "Prefs lock already held: " << kPrefsLockMachServiceName;
} }
return MACH_PORT_NULL; return base::mac::ScopedMachReceiveRight();
} }
return target_port; return target_right;
} }
// Sleep until the lock should be retried, up to an approximate maximum of // Sleep until the lock should be retried, up to an approximate maximum of
...@@ -72,10 +73,10 @@ namespace updater { ...@@ -72,10 +73,10 @@ namespace updater {
class ScopedPrefsLockImpl { class ScopedPrefsLockImpl {
public: public:
// Constructs a ScopedPrefsLockImpl from a receive right. // Constructs a ScopedPrefsLockImpl from a receive right.
explicit ScopedPrefsLockImpl(mach_port_t receive_port); explicit ScopedPrefsLockImpl(base::mac::ScopedMachReceiveRight receive_right);
// Releases the receive right (and therefore releases the lock). // Releases the receive right (and therefore releases the lock).
~ScopedPrefsLockImpl(); ~ScopedPrefsLockImpl() = default;
ScopedPrefsLockImpl(const ScopedPrefsLockImpl&) = delete; ScopedPrefsLockImpl(const ScopedPrefsLockImpl&) = delete;
ScopedPrefsLockImpl& operator=(const ScopedPrefsLockImpl&) = delete; ScopedPrefsLockImpl& operator=(const ScopedPrefsLockImpl&) = delete;
...@@ -83,28 +84,21 @@ class ScopedPrefsLockImpl { ...@@ -83,28 +84,21 @@ class ScopedPrefsLockImpl {
private: private:
// The Mach port representing the held lock itself. We only care about // The Mach port representing the held lock itself. We only care about
// service ownership; no messages are transfered with this port. // service ownership; no messages are transfered with this port.
mach_port_t receive_port_; base::mac::ScopedMachReceiveRight receive_right_;
}; };
ScopedPrefsLockImpl::ScopedPrefsLockImpl(mach_port_t receive_port) ScopedPrefsLockImpl::ScopedPrefsLockImpl(
: receive_port_(receive_port) { base::mac::ScopedMachReceiveRight receive_right)
// Verify the validity of the lock. : receive_right_(std::move(receive_right)) {
mach_port_type_t port_type = 0; mach_port_type_t port_type = 0;
kern_return_t port_check_result = kern_return_t port_check_result =
mach_port_type(mach_task_self(), receive_port, &port_type); mach_port_type(mach_task_self(), receive_right_.get(), &port_type);
MACH_CHECK(port_check_result == KERN_SUCCESS, port_check_result) MACH_CHECK(port_check_result == KERN_SUCCESS, port_check_result)
<< "ScopedPrefsLockImpl could not verify lock port"; << "ScopedPrefsLockImpl could not verify lock port";
CHECK(port_type & MACH_PORT_TYPE_RECEIVE) CHECK(port_type & MACH_PORT_TYPE_RECEIVE)
<< "ScopedPrefsLockImpl given port without receive right"; << "ScopedPrefsLockImpl given port without receive right";
} }
ScopedPrefsLockImpl::~ScopedPrefsLockImpl() {
kern_return_t destroy_result =
mach_port_destroy(mach_task_self(), receive_port_);
MACH_LOG_IF(ERROR, destroy_result != KERN_SUCCESS, destroy_result)
<< "ScopedPrefsLockImpl could not destroy port";
}
ScopedPrefsLock::ScopedPrefsLock(std::unique_ptr<ScopedPrefsLockImpl> impl) ScopedPrefsLock::ScopedPrefsLock(std::unique_ptr<ScopedPrefsLockImpl> impl)
: impl_(std::move(impl)) {} : impl_(std::move(impl)) {}
...@@ -114,7 +108,8 @@ std::unique_ptr<ScopedPrefsLock> AcquireGlobalPrefsLock( ...@@ -114,7 +108,8 @@ std::unique_ptr<ScopedPrefsLock> AcquireGlobalPrefsLock(
base::TimeDelta timeout) { base::TimeDelta timeout) {
// First, try to acquire the lock. If the timeout is zero or negative, // First, try to acquire the lock. If the timeout is zero or negative,
// this is the only attempt we will make. // this is the only attempt we will make.
mach_port_t lock_port = TryAcquireReceive(kPrefsLockMachServiceName); base::mac::ScopedMachReceiveRight receive_right(
TryAcquireReceive(kPrefsLockMachServiceName));
// Set up time limits. // Set up time limits.
base::TimeTicks deadline = base::TimeTicks::Now() + timeout; base::TimeTicks deadline = base::TimeTicks::Now() + timeout;
...@@ -126,16 +121,17 @@ std::unique_ptr<ScopedPrefsLock> AcquireGlobalPrefsLock( ...@@ -126,16 +121,17 @@ std::unique_ptr<ScopedPrefsLock> AcquireGlobalPrefsLock(
// this loop waits for retry *before* attempting to acquire the lock; // this loop waits for retry *before* attempting to acquire the lock;
// the special case of the first try was handled outside the loop. // the special case of the first try was handled outside the loop.
for (base::TimeDelta remain = deadline - base::TimeTicks::Now(); for (base::TimeDelta remain = deadline - base::TimeTicks::Now();
lock_port == MACH_PORT_NULL && remain > kDeltaZero; !receive_right.is_valid() && remain > kDeltaZero;
remain = deadline - base::TimeTicks::Now()) { remain = deadline - base::TimeTicks::Now()) {
WaitToRetryLock(remain); WaitToRetryLock(remain);
lock_port = TryAcquireReceive(kPrefsLockMachServiceName); receive_right = TryAcquireReceive(kPrefsLockMachServiceName);
} }
return lock_port == MACH_PORT_NULL if (!receive_right.is_valid()) {
? nullptr return nullptr;
: std::make_unique<ScopedPrefsLock>( }
std::make_unique<ScopedPrefsLockImpl>(lock_port)); return std::make_unique<ScopedPrefsLock>(
std::make_unique<ScopedPrefsLockImpl>(std::move(receive_right)));
} }
} // namespace updater } // namespace updater
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment