0

Revert "Remove base/mac/scoped_dispatch_object.h"

This reverts commit c22cb7957d.

Reason for revert: breaks libfuzzer mac asan bot

https://ci.chromium.org/ui/p/chromium/builders/ci/Libfuzzer%20Upload%20Mac%20ASan/82742/overview

Fixed: 1445156

Original change's description:
> Remove base/mac/scoped_dispatch_object.h
>
> In ARC, dispatch objects are Objective-C objects and need to be
> managed as such.
>
> See https://chromium.googlesource.com/chromium/src/+/main/docs/mac/arc.md
> for information about this conversion.
>
> Bug: 1280317
> Change-Id: I5db820ac85bd9aad54feab951c408c3e7785cb95
> Include-Ci-Only-Tests: true
> Validate-Test-Flakiness: skip
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4519014
> Reviewed-by: Chris Hamilton <chrisha@chromium.org>
> Owners-Override: Avi Drissman <avi@chromium.org>
> Reviewed-by: Mark Mentovai <mark@chromium.org>
> Commit-Queue: Avi Drissman <avi@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#1143321}

Bug: 1280317
Change-Id: I1363a4d7658a85d15bab4dbd0e5185a1fb8a09ad
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4527975
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Avi Drissman <avi@chromium.org>
Owners-Override: Avi Drissman <avi@chromium.org>
Reviewed-by: Avi Drissman <avi@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1143412}
This commit is contained in:
Nina Satragno
2023-05-12 18:19:32 +00:00
committed by Chromium LUCI CQ
parent d0f862d5e5
commit 76c48cc299
21 changed files with 213 additions and 276 deletions

@ -205,40 +205,6 @@ buildflag_header("message_pump_buildflags") {
flags = [ "ENABLE_MESSAGE_PUMP_EPOLL=$enable_message_pump_epoll" ]
}
if (is_apple) {
# TODO(https://crbug.com/1280317): Merge back into the `base` target once all
# .mm files are ARCed.
source_set("base_arc") {
sources = [
"mac/dispatch_source_mach.h",
"mac/dispatch_source_mach.mm",
]
configs += [ "//build/config/compiler:enable_arc" ]
deps = [
":base_static",
"//third_party/abseil-cpp:absl",
]
if (is_mac) {
sources += [
"files/file_path_watcher_fsevents.h",
"files/file_path_watcher_fsevents.mm",
"mac/mach_port_rendezvous.h",
"mac/mach_port_rendezvous.mm",
"synchronization/waitable_event_watcher_mac.mm",
]
libs = [ "bsm" ]
frameworks = [
"AppKit.framework",
"CoreServices.framework",
]
}
if (is_ios) {
frameworks = [ "UIKit.framework" ]
}
}
}
# Base and everything it depends on should be a static library rather than
# a source set. Base is more of a "library" in the classic sense in that many
# small parts of it are used in many different contexts. This combined with a
@ -2001,6 +1967,8 @@ component("base") {
"enterprise_util.cc",
"enterprise_util.h",
"enterprise_util_mac.mm",
"files/file_path_watcher_fsevents.cc",
"files/file_path_watcher_fsevents.h",
"files/file_path_watcher_kqueue.cc",
"files/file_path_watcher_kqueue.h",
"files/file_path_watcher_mac.cc",
@ -2013,6 +1981,8 @@ component("base") {
"mac/launchd.h",
"mac/mac_util.h",
"mac/mac_util.mm",
"mac/mach_port_rendezvous.cc",
"mac/mach_port_rendezvous.h",
"mac/os_crash_dumps.cc",
"mac/os_crash_dumps.h",
"mac/scoped_aedesc.h",
@ -2020,6 +1990,7 @@ component("base") {
"mac/scoped_authorizationref.mm",
"mac/scoped_cffiledescriptorref.h",
"mac/scoped_cftyperef.h",
"mac/scoped_dispatch_object.h",
"mac/scoped_ionotificationportref.h",
"mac/scoped_ioobject.h",
"mac/scoped_ioplugininterface.h",
@ -2053,6 +2024,7 @@ component("base") {
"profiler/stack_sampler_mac.cc",
"profiler/suspendable_thread_delegate_mac.cc",
"profiler/suspendable_thread_delegate_mac.h",
"synchronization/waitable_event_watcher_mac.cc",
"system/sys_info_mac.mm",
"time/time_exploded_posix.cc",
]
@ -2073,7 +2045,6 @@ component("base") {
# Mac or iOS.
if (is_apple) {
allow_circular_includes_from = [ ":base_arc" ]
sources += [
"apple/backup_util.h",
"apple/backup_util.mm",
@ -2086,6 +2057,8 @@ component("base") {
"mac/call_with_eh_frame.cc",
"mac/call_with_eh_frame.h",
"mac/call_with_eh_frame_asm.S",
"mac/dispatch_source_mach.cc",
"mac/dispatch_source_mach.h",
"mac/foundation_util.h",
"mac/foundation_util.mm",
"mac/mac_logging.h",
@ -2115,7 +2088,6 @@ component("base") {
"time/time_mac.mm",
]
frameworks += [ "Security.framework" ]
public_deps += [ ":base_arc" ]
}
# Linux.
@ -3492,10 +3464,7 @@ test("base_unittests") {
if (is_apple) {
public_deps = [ ":base_unittests_bundle_data" ]
deps += [
":base_arc",
":base_unittests_arc",
]
deps += [ ":base_unittests_arc" ]
}
if (!is_ios) {

@ -18,10 +18,6 @@
#include "base/task/sequenced_task_runner.h"
#include "base/threading/scoped_blocking_call.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace base {
namespace {
@ -34,8 +30,8 @@ FilePath ResolvePath(const FilePath& path) {
const unsigned kMaxLinksToResolve = 255;
std::vector<FilePath::StringType> component_vector = path.GetComponents();
std::list<FilePath::StringType> components(component_vector.begin(),
component_vector.end());
std::list<FilePath::StringType>
components(component_vector.begin(), component_vector.end());
FilePath result;
unsigned resolve_count = 0;
@ -52,9 +48,8 @@ FilePath ResolvePath(const FilePath& path) {
FilePath target;
if (ReadSymbolicLink(current, &target)) {
if (target.IsAbsolute()) {
if (target.IsAbsolute())
result.clear();
}
std::vector<FilePath::StringType> target_components =
target.GetComponents();
components.insert(components.begin(), target_components.begin(),
@ -65,25 +60,18 @@ FilePath ResolvePath(const FilePath& path) {
}
}
if (resolve_count >= kMaxLinksToResolve) {
if (resolve_count >= kMaxLinksToResolve)
result.clear();
}
return result;
}
} // namespace
struct FilePathWatcherFSEvents::ObjCStorage {
// The dispatch queue on which the event stream is scheduled.
dispatch_queue_t __strong queue;
};
FilePathWatcherFSEvents::FilePathWatcherFSEvents()
: objc_storage_(std::make_unique<ObjCStorage>()) {
objc_storage_->queue = dispatch_queue_create(
base::StringPrintf("org.chromium.base.FilePathWatcher.%p", this).c_str(),
DISPATCH_QUEUE_SERIAL);
}
: queue_(dispatch_queue_create(
base::StringPrintf("org.chromium.base.FilePathWatcher.%p", this)
.c_str(),
DISPATCH_QUEUE_SERIAL)) {}
FilePathWatcherFSEvents::~FilePathWatcherFSEvents() {
DCHECK(!task_runner() || task_runner()->RunsTasksInCurrentSequence());
@ -99,9 +87,8 @@ bool FilePathWatcherFSEvents::Watch(const FilePath& path,
// This class could support non-recursive watches, but that is currently
// left to FilePathWatcherKQueue.
if (type != Type::kRecursive) {
if (type != Type::kRecursive)
return false;
}
set_task_runner(SequencedTaskRunner::GetCurrentDefault());
callback_ = callback;
@ -112,8 +99,8 @@ bool FilePathWatcherFSEvents::Watch(const FilePath& path,
// captured by the block's scope.
const FilePath path_copy(path);
dispatch_async(objc_storage_->queue, ^{
StartEventStream(start_event, path_copy);
dispatch_async(queue_, ^{
StartEventStream(start_event, path_copy);
});
return true;
}
@ -126,7 +113,7 @@ void FilePathWatcherFSEvents::Cancel() {
// Switch to the dispatch queue to tear down the event stream. As the queue is
// owned by |this|, and this method is called from the destructor, execute the
// block synchronously.
dispatch_sync(objc_storage_->queue, ^{
dispatch_sync(queue_, ^{
if (fsevent_stream_) {
DestroyEventStream();
target_.clear();
@ -149,14 +136,12 @@ void FilePathWatcherFSEvents::FSEventsCallback(
std::vector<FilePath> paths;
FSEventStreamEventId root_change_at = FSEventStreamGetLatestEventId(stream);
for (size_t i = 0; i < num_events; i++) {
if (flags[i] & kFSEventStreamEventFlagRootChanged) {
if (flags[i] & kFSEventStreamEventFlagRootChanged)
root_changed = true;
}
if (event_ids[i]) {
if (event_ids[i])
root_change_at = std::min(root_change_at, event_ids[i]);
}
paths.push_back(FilePath(reinterpret_cast<char**>(event_paths)[i])
.StripTrailingSeparators());
paths.push_back(FilePath(
reinterpret_cast<char**>(event_paths)[i]).StripTrailingSeparators());
}
// Reinitialize the event stream if we find changes to the root. This is
@ -178,11 +163,10 @@ void FilePathWatcherFSEvents::FSEventsCallback(
FROM_HERE, BindOnce(
[](WeakPtr<FilePathWatcherFSEvents> weak_watcher,
FSEventStreamEventId root_change_at) {
if (!weak_watcher) {
if (!weak_watcher)
return;
}
FilePathWatcherFSEvents* watcher = weak_watcher.get();
dispatch_async(watcher->objc_storage_->queue, ^{
dispatch_async(watcher->queue_, ^{
watcher->UpdateEventStream(root_change_at);
});
},
@ -223,35 +207,35 @@ void FilePathWatcherFSEvents::UpdateEventStream(
FSEventStreamEventId start_event) {
// It can happen that the watcher gets canceled while tasks that call this
// function are still in flight, so abort if this situation is detected.
if (resolved_target_.empty()) {
if (resolved_target_.empty())
return;
}
if (fsevent_stream_) {
if (fsevent_stream_)
DestroyEventStream();
}
ScopedCFTypeRef<CFStringRef> cf_path(CFStringCreateWithCString(
nullptr, resolved_target_.value().c_str(), kCFStringEncodingMacHFS));
NULL, resolved_target_.value().c_str(), kCFStringEncodingMacHFS));
ScopedCFTypeRef<CFStringRef> cf_dir_path(CFStringCreateWithCString(
nullptr, resolved_target_.DirName().value().c_str(),
NULL, resolved_target_.DirName().value().c_str(),
kCFStringEncodingMacHFS));
CFStringRef paths_array[] = {cf_path.get(), cf_dir_path.get()};
CFStringRef paths_array[] = { cf_path.get(), cf_dir_path.get() };
ScopedCFTypeRef<CFArrayRef> watched_paths(
CFArrayCreate(nullptr, reinterpret_cast<const void**>(paths_array),
CFArrayCreate(NULL, reinterpret_cast<const void**>(paths_array),
std::size(paths_array), &kCFTypeArrayCallBacks));
FSEventStreamContext context;
context.version = 0;
context.info = this;
context.retain = nullptr;
context.release = nullptr;
context.copyDescription = nullptr;
context.retain = NULL;
context.release = NULL;
context.copyDescription = NULL;
fsevent_stream_ = FSEventStreamCreate(
nullptr, &FSEventsCallback, &context, watched_paths, start_event,
kEventLatencySeconds, kFSEventStreamCreateFlagWatchRoot);
FSEventStreamSetDispatchQueue(fsevent_stream_, objc_storage_->queue);
fsevent_stream_ = FSEventStreamCreate(NULL, &FSEventsCallback, &context,
watched_paths,
start_event,
kEventLatencySeconds,
kFSEventStreamCreateFlagWatchRoot);
FSEventStreamSetDispatchQueue(fsevent_stream_, queue_);
if (!FSEventStreamStart(fsevent_stream_)) {
task_runner()->PostTask(FROM_HERE,
@ -283,7 +267,7 @@ void FilePathWatcherFSEvents::DestroyEventStream() {
FSEventStreamStop(fsevent_stream_);
FSEventStreamInvalidate(fsevent_stream_);
FSEventStreamRelease(fsevent_stream_);
fsevent_stream_ = nullptr;
fsevent_stream_ = NULL;
}
void FilePathWatcherFSEvents::StartEventStream(FSEventStreamEventId start_event,

@ -12,6 +12,7 @@
#include "base/files/file_path.h"
#include "base/files/file_path_watcher.h"
#include "base/mac/scoped_dispatch_object.h"
#include "base/memory/weak_ptr.h"
namespace base {
@ -74,6 +75,9 @@ class FilePathWatcherFSEvents : public FilePathWatcher::PlatformDelegate {
// (Only accessed from the task_runner() thread.)
FilePathWatcher::Callback callback_;
// The dispatch queue on which the event stream is scheduled.
ScopedDispatchObject<dispatch_queue_t> queue_;
// Target path to watch (passed to callback).
// (Only accessed from the libdispatch queue.)
FilePath target_;
@ -86,9 +90,6 @@ class FilePathWatcherFSEvents : public FilePathWatcher::PlatformDelegate {
// (Only accessed from the libdispatch queue.)
FSEventStreamRef fsevent_stream_ = nullptr;
struct ObjCStorage;
std::unique_ptr<ObjCStorage> objc_storage_;
WeakPtrFactory<FilePathWatcherFSEvents> weak_factory_{this};
};

@ -0,0 +1,46 @@
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/mac/dispatch_source_mach.h"
namespace base {
DispatchSourceMach::DispatchSourceMach(const char* name,
mach_port_t port,
void (^event_handler)())
: DispatchSourceMach(dispatch_queue_create(name, DISPATCH_QUEUE_SERIAL),
port,
event_handler) {
// Since the queue was created above in the delegated constructor, and it was
// subsequently retained, release it here.
dispatch_release(queue_);
}
DispatchSourceMach::DispatchSourceMach(dispatch_queue_t queue,
mach_port_t port,
void (^event_handler)())
: queue_(queue, base::scoped_policy::RETAIN),
source_(dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV,
port, 0, queue_)),
source_canceled_(dispatch_semaphore_create(0)) {
dispatch_source_set_event_handler(source_, event_handler);
dispatch_source_set_cancel_handler(source_, ^{
dispatch_semaphore_signal(source_canceled_);
});
}
DispatchSourceMach::~DispatchSourceMach() {
// Cancel the source and wait for the semaphore to be signaled. This will
// ensure the source managed by this class is not used after it is freed.
dispatch_source_cancel(source_);
source_.reset();
dispatch_semaphore_wait(source_canceled_, DISPATCH_TIME_FOREVER);
}
void DispatchSourceMach::Resume() {
dispatch_resume(source_);
}
} // namespace base

@ -7,9 +7,8 @@
#include <dispatch/dispatch.h>
#include <memory>
#include "base/base_export.h"
#include "base/mac/scoped_dispatch_object.h"
namespace base {
@ -43,11 +42,17 @@ class BASE_EXPORT DispatchSourceMach {
// be received.
void Resume();
dispatch_queue_t queue() const;
dispatch_queue_t queue() const { return queue_.get(); }
private:
struct ObjCStorage;
std::unique_ptr<ObjCStorage> objc_storage_;
// The dispatch queue used to service the source_.
ScopedDispatchObject<dispatch_queue_t> queue_;
// A MACH_RECV dispatch source.
ScopedDispatchObject<dispatch_source_t> source_;
// Semaphore used to wait on the |source_|'s cancellation in the destructor.
ScopedDispatchObject<dispatch_semaphore_t> source_canceled_;
};
} // namespace base

@ -1,64 +0,0 @@
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/mac/dispatch_source_mach.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace base {
struct DispatchSourceMach::ObjCStorage {
// The dispatch queue used to service the source_.
dispatch_queue_t __strong queue;
// A MACH_RECV dispatch source.
dispatch_source_t __strong source;
// Semaphore used to wait on the |source_|'s cancellation in the destructor.
dispatch_semaphore_t __strong source_canceled;
};
DispatchSourceMach::DispatchSourceMach(const char* name,
mach_port_t port,
void (^event_handler)())
: DispatchSourceMach(dispatch_queue_create(name, DISPATCH_QUEUE_SERIAL),
port,
event_handler) {}
DispatchSourceMach::DispatchSourceMach(dispatch_queue_t queue,
mach_port_t port,
void (^event_handler)())
: objc_storage_(std::make_unique<ObjCStorage>()) {
objc_storage_->queue = queue;
objc_storage_->source = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV,
port, /*mask=*/0, queue);
objc_storage_->source_canceled = dispatch_semaphore_create(/*value=*/0);
dispatch_source_set_event_handler(objc_storage_->source, event_handler);
dispatch_source_set_cancel_handler(objc_storage_->source, ^{
dispatch_semaphore_signal(objc_storage_->source_canceled);
});
}
DispatchSourceMach::~DispatchSourceMach() {
// Cancel the source and wait for the semaphore to be signaled. This will
// ensure the source managed by this class is not used after it is freed.
dispatch_source_cancel(objc_storage_->source);
objc_storage_->source = nil;
dispatch_semaphore_wait(objc_storage_->source_canceled,
DISPATCH_TIME_FOREVER);
}
void DispatchSourceMach::Resume() {
dispatch_resume(objc_storage_->source);
}
dispatch_queue_t DispatchSourceMach::queue() const {
return objc_storage_->queue;
}
} // namespace base

@ -17,10 +17,6 @@
#include "base/notreached.h"
#include "base/strings/stringprintf.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
#if BUILDFLAG(IS_IOS)
#include "base/ios/sim_header_shims.h"
#else
@ -107,19 +103,6 @@ void MachRendezvousPort::Destroy() {
disposition_ = 0;
}
struct MachPortRendezvousServer::ClientData {
ClientData(dispatch_source_t exit_watcher, MachPortsForRendezvous ports)
: exit_watcher(exit_watcher), ports(ports) {}
ClientData(ClientData&&) = default;
~ClientData() = default;
// A DISPATCH_SOURCE_TYPE_PROC / DISPATCH_PROC_EXIT dispatch source. When
// the source is triggered, it calls OnClientExited().
dispatch_source_t __strong exit_watcher;
MachPortsForRendezvous ports;
};
// static
MachPortRendezvousServer* MachPortRendezvousServer::GetInstance() {
static auto* instance = new MachPortRendezvousServer();
@ -133,9 +116,9 @@ void MachPortRendezvousServer::RegisterPortsForPid(
DCHECK_LT(ports.size(), kMaximumRendezvousPorts);
DCHECK(!ports.empty());
dispatch_source_t exit_watcher = dispatch_source_create(
ScopedDispatchObject<dispatch_source_t> exit_watcher(dispatch_source_create(
DISPATCH_SOURCE_TYPE_PROC, static_cast<uintptr_t>(pid),
DISPATCH_PROC_EXIT, dispatch_source_->queue());
DISPATCH_PROC_EXIT, dispatch_source_->queue()));
dispatch_source_set_event_handler(exit_watcher, ^{
OnClientExited(pid);
});
@ -146,6 +129,15 @@ void MachPortRendezvousServer::RegisterPortsForPid(
DCHECK(it.second);
}
MachPortRendezvousServer::ClientData::ClientData(
ScopedDispatchObject<dispatch_source_t> exit_watcher,
MachPortsForRendezvous ports)
: exit_watcher(exit_watcher), ports(ports) {}
MachPortRendezvousServer::ClientData::ClientData(ClientData&&) = default;
MachPortRendezvousServer::ClientData::~ClientData() = default;
MachPortRendezvousServer::MachPortRendezvousServer() {
std::string bootstrap_name =
StringPrintf(kBootstrapNameFormat, mac::BaseBundleID(), getpid());
@ -162,7 +154,7 @@ MachPortRendezvousServer::MachPortRendezvousServer() {
dispatch_source_->Resume();
}
MachPortRendezvousServer::~MachPortRendezvousServer() = default;
MachPortRendezvousServer::~MachPortRendezvousServer() {}
void MachPortRendezvousServer::HandleRequest() {
// Receive the request message, using the kernel audit token to ascertain the
@ -280,7 +272,8 @@ MachPortRendezvousClient* MachPortRendezvousClient::GetInstance() {
client = nullptr;
}
return client;
}();
}
();
return client;
}

@ -16,6 +16,7 @@
#include "base/base_export.h"
#include "base/mac/dispatch_source_mach.h"
#include "base/mac/scoped_dispatch_object.h"
#include "base/mac/scoped_mach_port.h"
#include "base/synchronization/lock.h"
#include "base/thread_annotations.h"
@ -107,6 +108,19 @@ class BASE_EXPORT MachPortRendezvousServer {
friend class MachPortRendezvousServerTest;
friend struct MachPortRendezvousFuzzer;
struct ClientData {
ClientData(ScopedDispatchObject<dispatch_source_t> exit_watcher,
MachPortsForRendezvous ports);
ClientData(ClientData&&);
~ClientData();
// A DISPATCH_SOURCE_TYPE_PROC / DISPATCH_PROC_EXIT dispatch source. When
// the source is triggered, it calls OnClientExited().
ScopedDispatchObject<dispatch_source_t> exit_watcher;
MachPortsForRendezvous ports;
};
MachPortRendezvousServer();
~MachPortRendezvousServer();
@ -138,7 +152,6 @@ class BASE_EXPORT MachPortRendezvousServer {
// Mach message dispatch source for |server_port_|.
std::unique_ptr<DispatchSourceMach> dispatch_source_;
struct ClientData;
Lock lock_;
// Association of pid-to-ports.
std::map<pid_t, ClientData> client_data_ GUARDED_BY(lock_);

@ -0,0 +1,36 @@
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_MAC_SCOPED_DISPATCH_OBJECT_H_
#define BASE_MAC_SCOPED_DISPATCH_OBJECT_H_
#include <dispatch/dispatch.h>
#include "base/mac/scoped_typeref.h"
namespace base {
namespace internal {
template <typename T>
struct ScopedDispatchObjectTraits {
static constexpr T InvalidValue() { return nullptr; }
static T Retain(T object) {
dispatch_retain(object);
return object;
}
static void Release(T object) {
dispatch_release(object);
}
};
} // namespace internal
template <typename T>
using ScopedDispatchObject =
ScopedTypeRef<T, internal::ScopedDispatchObjectTraits<T>>;
} // namespace base
#endif // BASE_MAC_SCOPED_DISPATCH_OBJECT_H_

@ -16,8 +16,7 @@
#elif BUILDFLAG(IS_APPLE)
#include <dispatch/dispatch.h>
#include <memory>
#include "base/mac/scoped_dispatch_object.h"
#include "base/memory/weak_ptr.h"
#include "base/synchronization/waitable_event.h"
#else
@ -132,8 +131,10 @@ class BASE_EXPORT WaitableEventWatcher
// is waiting. Null if no event is being watched.
scoped_refptr<WaitableEvent::ReceiveRight> receive_right_;
struct ObjCStorage;
std::unique_ptr<ObjCStorage> objc_storage_;
// A TYPE_MACH_RECV dispatch source on |receive_right_|. When a receive event
// is delivered, the message queue will be peeked and the bound |callback_|
// may be run. This will be null if nothing is currently being watched.
ScopedDispatchObject<dispatch_source_t> source_;
// Used to vend a weak pointer for calling InvokeCallback() from the
// |source_| event handler.

@ -7,21 +7,9 @@
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace base {
struct WaitableEventWatcher::ObjCStorage {
// A TYPE_MACH_RECV dispatch source on |receive_right_|. When a receive event
// is delivered, the message queue will be peeked and the bound |callback_|
// may be run. This will be null if nothing is currently being watched.
dispatch_source_t __strong source;
};
WaitableEventWatcher::WaitableEventWatcher()
: objc_storage_(std::make_unique<ObjCStorage>()), weak_ptr_factory_(this) {}
WaitableEventWatcher::WaitableEventWatcher() : weak_ptr_factory_(this) {}
WaitableEventWatcher::~WaitableEventWatcher() {
StopWatching();
@ -32,8 +20,7 @@ bool WaitableEventWatcher::StartWatching(
EventCallback callback,
scoped_refptr<SequencedTaskRunner> task_runner) {
DCHECK(task_runner->RunsTasksInCurrentSequence());
DCHECK(!objc_storage_->source ||
dispatch_source_testcancel(objc_storage_->source));
DCHECK(!source_ || dispatch_source_testcancel(source_));
// Keep a reference to the receive right, so that if the event is deleted
// out from under the watcher, a signal can still be observed.
@ -43,9 +30,9 @@ bool WaitableEventWatcher::StartWatching(
// Use the global concurrent queue here, since it is only used to thunk
// to the real callback on the target task runner.
objc_storage_->source = dispatch_source_create(
DISPATCH_SOURCE_TYPE_MACH_RECV, receive_right_->Name(), /*mask=*/0,
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, /*flags=*/0));
source_.reset(dispatch_source_create(
DISPATCH_SOURCE_TYPE_MACH_RECV, receive_right_->Name(), 0,
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)));
// Locals for capture by the block. Accessing anything through the |this| or
// |event| pointers is not safe, since either may have been deleted by the
@ -53,10 +40,10 @@ bool WaitableEventWatcher::StartWatching(
WeakPtr<WaitableEventWatcher> weak_this = weak_ptr_factory_.GetWeakPtr();
const bool auto_reset =
event->policy_ == WaitableEvent::ResetPolicy::AUTOMATIC;
dispatch_source_t source = objc_storage_->source;
dispatch_source_t source = source_.get();
mach_port_t name = receive_right_->Name();
dispatch_source_set_event_handler(objc_storage_->source, ^{
dispatch_source_set_event_handler(source_, ^{
// For automatic-reset events, only fire the callback if this watcher
// can claim/dequeue the event. For manual-reset events, all watchers can
// be called back.
@ -71,7 +58,7 @@ bool WaitableEventWatcher::StartWatching(
task_runner->PostTask(
FROM_HERE, BindOnce(&WaitableEventWatcher::InvokeCallback, weak_this));
});
dispatch_resume(objc_storage_->source);
dispatch_resume(source_);
return true;
}
@ -79,19 +66,18 @@ bool WaitableEventWatcher::StartWatching(
void WaitableEventWatcher::StopWatching() {
callback_.Reset();
receive_right_ = nullptr;
if (objc_storage_->source) {
dispatch_source_cancel(objc_storage_->source);
objc_storage_->source = nil;
if (source_) {
dispatch_source_cancel(source_);
source_.reset();
}
}
void WaitableEventWatcher::InvokeCallback() {
// The callback can be null if StopWatching() is called between signaling
// and the |callback_| getting run on the target task runner.
if (callback_.is_null()) {
if (callback_.is_null())
return;
}
objc_storage_->source = nil;
source_.reset();
receive_right_ = nullptr;
std::move(callback_).Run();
}

@ -30,10 +30,9 @@ source_set("memory_pressure") {
if (is_apple) {
sources += [
"system_memory_pressure_evaluator_mac.cc",
"system_memory_pressure_evaluator_mac.h",
"system_memory_pressure_evaluator_mac.mm",
]
configs += [ "//build/config/compiler:enable_arc" ]
}
if (is_fuchsia) {

@ -19,10 +19,6 @@
#include "base/memory/memory_pressure_monitor.h"
#include "base/task/sequenced_task_runner.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace memory_pressure::mac {
namespace {
@ -47,28 +43,22 @@ SystemMemoryPressureEvaluator::MemoryPressureLevelForMacMemoryPressureLevel(
return base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
}
struct SystemMemoryPressureEvaluator::ObjCStorage {
// The dispatch source that generates memory pressure change notifications.
dispatch_source_t __strong memory_level_event_source;
};
SystemMemoryPressureEvaluator::SystemMemoryPressureEvaluator(
std::unique_ptr<MemoryPressureVoter> voter)
: memory_pressure::SystemMemoryPressureEvaluator(std::move(voter)),
memory_level_event_source_(dispatch_source_create(
DISPATCH_SOURCE_TYPE_MEMORYPRESSURE,
0,
DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL |
DISPATCH_MEMORYPRESSURE_NORMAL,
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0))),
renotify_current_vote_timer_(
FROM_HERE,
kRenotifyVotePeriod,
base::BindRepeating(&SystemMemoryPressureEvaluator::SendCurrentVote,
base::Unretained(this),
/*notify=*/true)),
objc_storage_(std::make_unique<ObjCStorage>()),
weak_ptr_factory_(this) {
objc_storage_->memory_level_event_source = dispatch_source_create(
DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, /*handle=*/0,
DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL |
DISPATCH_MEMORYPRESSURE_NORMAL,
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, /*flags=*/0));
// WeakPtr needed because there is no guarantee that |this| is still be alive
// when the task posted to the TaskRunner or event handler runs.
base::WeakPtr<SystemMemoryPressureEvaluator> weak_this =
@ -77,25 +67,24 @@ SystemMemoryPressureEvaluator::SystemMemoryPressureEvaluator(
base::SequencedTaskRunner::GetCurrentDefault();
// Attach an event handler to the memory pressure event source.
if (objc_storage_->memory_level_event_source) {
dispatch_source_set_event_handler(
objc_storage_->memory_level_event_source, ^{
task_runner->PostTask(
FROM_HERE,
base::BindRepeating(
&SystemMemoryPressureEvaluator::OnMemoryPressureChanged,
weak_this));
});
if (memory_level_event_source_.get()) {
dispatch_source_set_event_handler(memory_level_event_source_, ^{
task_runner->PostTask(
FROM_HERE,
base::BindRepeating(
&SystemMemoryPressureEvaluator::OnMemoryPressureChanged,
weak_this));
});
// Start monitoring the event source.
dispatch_resume(objc_storage_->memory_level_event_source);
dispatch_resume(memory_level_event_source_);
}
}
SystemMemoryPressureEvaluator::~SystemMemoryPressureEvaluator() {
// Remove the memory pressure event source.
if (objc_storage_->memory_level_event_source) {
dispatch_source_cancel(objc_storage_->memory_level_event_source);
if (memory_level_event_source_.get()) {
dispatch_source_cancel(memory_level_event_source_);
}
}
@ -126,7 +115,7 @@ void SystemMemoryPressureEvaluator::OnMemoryPressureChanged() {
UpdatePressureLevel();
// Run the callback that's waiting on memory pressure change notifications.
// The convention is to not send notifications on memory pressure returning to
// The convention is to not send notifiations on memory pressure returning to
// normal.
bool notify = current_vote() !=
base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;

@ -9,13 +9,15 @@
#include <dispatch/dispatch.h>
#include "base/mac/scoped_cftyperef.h"
#include "base/mac/scoped_dispatch_object.h"
#include "base/message_loop/message_pump_mac.h"
#include "base/sequence_checker.h"
#include "base/timer/timer.h"
#include "components/memory_pressure/memory_pressure_voter.h"
#include "components/memory_pressure/system_memory_pressure_evaluator.h"
namespace memory_pressure::mac {
namespace memory_pressure {
namespace mac {
class TestSystemMemoryPressureEvaluator;
@ -48,17 +50,18 @@ class SystemMemoryPressureEvaluator
// Run |dispatch_callback| on memory pressure notifications from the OS.
void OnMemoryPressureChanged();
// The dispatch source that generates memory pressure change notifications.
base::ScopedDispatchObject<dispatch_source_t> memory_level_event_source_;
// Timer that will re-notify with the current vote at regular interval.
base::RepeatingTimer renotify_current_vote_timer_;
struct ObjCStorage;
std::unique_ptr<ObjCStorage> objc_storage_;
SEQUENCE_CHECKER(sequence_checker_);
base::WeakPtrFactory<SystemMemoryPressureEvaluator> weak_ptr_factory_;
};
} // namespace memory_pressure::mac
} // namespace mac
} // namespace memory_pressure
#endif // COMPONENTS_MEMORY_PRESSURE_SYSTEM_MEMORY_PRESSURE_EVALUATOR_MAC_H_

@ -41,10 +41,6 @@ if (enable_nacl) {
"//native_client/src/trusted/error_code",
"//services/service_manager/public/cpp",
]
if (is_apple) {
deps += [ "//base:base_arc" ]
}
}
# This exists just to make 'gn check' happy with :minimal. It can't

@ -37,7 +37,6 @@ static_library("named_mojo_ipc_server") {
sources += [ "named_mojo_server_endpoint_connector_win.cc" ]
} else if (is_mac) {
sources += [ "named_mojo_server_endpoint_connector_mac.cc" ]
deps += [ "//base:base_arc" ]
} else {
sources += [ "named_mojo_server_endpoint_connector_unsupported.cc" ]
}

@ -142,10 +142,6 @@ target(link_target_type, "child") {
libs = [ "dwrite.lib" ]
}
if (is_apple) {
deps += [ "//base:base_arc" ]
}
if (is_mac) {
sources += [
"child_process_sandbox_support_impl_mac.cc",

@ -99,9 +99,7 @@ component("ipc") {
"//services/tracing/public/cpp",
]
if (is_apple) {
public_deps += [ "//base:base_arc" ]
}
deps = [ "//base" ]
if (enable_ipc_fuzzer) {
public_configs = [ "//tools/ipc_fuzzer:ipc_fuzzer_config" ]

@ -58,10 +58,6 @@ component("platform") {
deps += [ "//net" ]
}
if (is_apple) {
public_deps += [ "//base:base_arc" ]
}
if (is_mac) {
sources += [ "named_platform_channel_mac.cc" ]
}

@ -65,10 +65,6 @@ source_set("service_manager") {
"//mojo/core/embedder",
"//services/service_manager/public/cpp/service_executable:switches",
]
if (is_mac) {
public_deps += [ "//base:base_arc" ]
}
}
if (is_linux || is_chromeos) {

@ -176,7 +176,6 @@ blink_platform_sources("loader") {
deps = [
":make_platform_loader_generated_delivery_type_names",
":make_platform_loader_generated_fetch_initiator_type_names",
"//base",
"//components/link_header_util",
"//components/variations/net:net",
"//net",
@ -198,10 +197,6 @@ blink_platform_sources("loader") {
]
allow_circular_includes_from =
[ "//third_party/blink/renderer/platform/network:network" ]
if (is_apple) {
deps += [ "//base:base_arc" ]
}
}
source_set("unit_tests") {