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:

committed by
Chromium LUCI CQ

parent
d0f862d5e5
commit
76c48cc299
base
BUILD.gn
files
mac
dispatch_source_mach.ccdispatch_source_mach.hdispatch_source_mach.mmmach_port_rendezvous.ccmach_port_rendezvous.hscoped_dispatch_object.h
synchronization
components
memory_pressure
nacl
common
named_mojo_ipc_server
content/child
ipc
mojo/public/cpp/platform
services/service_manager
third_party/blink/renderer/platform/loader
@ -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};
|
||||
};
|
||||
|
||||
|
46
base/mac/dispatch_source_mach.cc
Normal file
46
base/mac/dispatch_source_mach.cc
Normal file
@ -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_);
|
||||
|
36
base/mac/scoped_dispatch_object.h
Normal file
36
base/mac/scoped_dispatch_object.h
Normal file
@ -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") {
|
||||
|
Reference in New Issue
Block a user