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" ]
|
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
|
# 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
|
# 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
|
# 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.cc",
|
||||||
"enterprise_util.h",
|
"enterprise_util.h",
|
||||||
"enterprise_util_mac.mm",
|
"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.cc",
|
||||||
"files/file_path_watcher_kqueue.h",
|
"files/file_path_watcher_kqueue.h",
|
||||||
"files/file_path_watcher_mac.cc",
|
"files/file_path_watcher_mac.cc",
|
||||||
@ -2013,6 +1981,8 @@ component("base") {
|
|||||||
"mac/launchd.h",
|
"mac/launchd.h",
|
||||||
"mac/mac_util.h",
|
"mac/mac_util.h",
|
||||||
"mac/mac_util.mm",
|
"mac/mac_util.mm",
|
||||||
|
"mac/mach_port_rendezvous.cc",
|
||||||
|
"mac/mach_port_rendezvous.h",
|
||||||
"mac/os_crash_dumps.cc",
|
"mac/os_crash_dumps.cc",
|
||||||
"mac/os_crash_dumps.h",
|
"mac/os_crash_dumps.h",
|
||||||
"mac/scoped_aedesc.h",
|
"mac/scoped_aedesc.h",
|
||||||
@ -2020,6 +1990,7 @@ component("base") {
|
|||||||
"mac/scoped_authorizationref.mm",
|
"mac/scoped_authorizationref.mm",
|
||||||
"mac/scoped_cffiledescriptorref.h",
|
"mac/scoped_cffiledescriptorref.h",
|
||||||
"mac/scoped_cftyperef.h",
|
"mac/scoped_cftyperef.h",
|
||||||
|
"mac/scoped_dispatch_object.h",
|
||||||
"mac/scoped_ionotificationportref.h",
|
"mac/scoped_ionotificationportref.h",
|
||||||
"mac/scoped_ioobject.h",
|
"mac/scoped_ioobject.h",
|
||||||
"mac/scoped_ioplugininterface.h",
|
"mac/scoped_ioplugininterface.h",
|
||||||
@ -2053,6 +2024,7 @@ component("base") {
|
|||||||
"profiler/stack_sampler_mac.cc",
|
"profiler/stack_sampler_mac.cc",
|
||||||
"profiler/suspendable_thread_delegate_mac.cc",
|
"profiler/suspendable_thread_delegate_mac.cc",
|
||||||
"profiler/suspendable_thread_delegate_mac.h",
|
"profiler/suspendable_thread_delegate_mac.h",
|
||||||
|
"synchronization/waitable_event_watcher_mac.cc",
|
||||||
"system/sys_info_mac.mm",
|
"system/sys_info_mac.mm",
|
||||||
"time/time_exploded_posix.cc",
|
"time/time_exploded_posix.cc",
|
||||||
]
|
]
|
||||||
@ -2073,7 +2045,6 @@ component("base") {
|
|||||||
|
|
||||||
# Mac or iOS.
|
# Mac or iOS.
|
||||||
if (is_apple) {
|
if (is_apple) {
|
||||||
allow_circular_includes_from = [ ":base_arc" ]
|
|
||||||
sources += [
|
sources += [
|
||||||
"apple/backup_util.h",
|
"apple/backup_util.h",
|
||||||
"apple/backup_util.mm",
|
"apple/backup_util.mm",
|
||||||
@ -2086,6 +2057,8 @@ component("base") {
|
|||||||
"mac/call_with_eh_frame.cc",
|
"mac/call_with_eh_frame.cc",
|
||||||
"mac/call_with_eh_frame.h",
|
"mac/call_with_eh_frame.h",
|
||||||
"mac/call_with_eh_frame_asm.S",
|
"mac/call_with_eh_frame_asm.S",
|
||||||
|
"mac/dispatch_source_mach.cc",
|
||||||
|
"mac/dispatch_source_mach.h",
|
||||||
"mac/foundation_util.h",
|
"mac/foundation_util.h",
|
||||||
"mac/foundation_util.mm",
|
"mac/foundation_util.mm",
|
||||||
"mac/mac_logging.h",
|
"mac/mac_logging.h",
|
||||||
@ -2115,7 +2088,6 @@ component("base") {
|
|||||||
"time/time_mac.mm",
|
"time/time_mac.mm",
|
||||||
]
|
]
|
||||||
frameworks += [ "Security.framework" ]
|
frameworks += [ "Security.framework" ]
|
||||||
public_deps += [ ":base_arc" ]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Linux.
|
# Linux.
|
||||||
@ -3492,10 +3464,7 @@ test("base_unittests") {
|
|||||||
if (is_apple) {
|
if (is_apple) {
|
||||||
public_deps = [ ":base_unittests_bundle_data" ]
|
public_deps = [ ":base_unittests_bundle_data" ]
|
||||||
|
|
||||||
deps += [
|
deps += [ ":base_unittests_arc" ]
|
||||||
":base_arc",
|
|
||||||
":base_unittests_arc",
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_ios) {
|
if (!is_ios) {
|
||||||
|
@ -18,10 +18,6 @@
|
|||||||
#include "base/task/sequenced_task_runner.h"
|
#include "base/task/sequenced_task_runner.h"
|
||||||
#include "base/threading/scoped_blocking_call.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 base {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -34,8 +30,8 @@ FilePath ResolvePath(const FilePath& path) {
|
|||||||
const unsigned kMaxLinksToResolve = 255;
|
const unsigned kMaxLinksToResolve = 255;
|
||||||
|
|
||||||
std::vector<FilePath::StringType> component_vector = path.GetComponents();
|
std::vector<FilePath::StringType> component_vector = path.GetComponents();
|
||||||
std::list<FilePath::StringType> components(component_vector.begin(),
|
std::list<FilePath::StringType>
|
||||||
component_vector.end());
|
components(component_vector.begin(), component_vector.end());
|
||||||
|
|
||||||
FilePath result;
|
FilePath result;
|
||||||
unsigned resolve_count = 0;
|
unsigned resolve_count = 0;
|
||||||
@ -52,9 +48,8 @@ FilePath ResolvePath(const FilePath& path) {
|
|||||||
|
|
||||||
FilePath target;
|
FilePath target;
|
||||||
if (ReadSymbolicLink(current, &target)) {
|
if (ReadSymbolicLink(current, &target)) {
|
||||||
if (target.IsAbsolute()) {
|
if (target.IsAbsolute())
|
||||||
result.clear();
|
result.clear();
|
||||||
}
|
|
||||||
std::vector<FilePath::StringType> target_components =
|
std::vector<FilePath::StringType> target_components =
|
||||||
target.GetComponents();
|
target.GetComponents();
|
||||||
components.insert(components.begin(), target_components.begin(),
|
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();
|
result.clear();
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
struct FilePathWatcherFSEvents::ObjCStorage {
|
|
||||||
// The dispatch queue on which the event stream is scheduled.
|
|
||||||
dispatch_queue_t __strong queue;
|
|
||||||
};
|
|
||||||
|
|
||||||
FilePathWatcherFSEvents::FilePathWatcherFSEvents()
|
FilePathWatcherFSEvents::FilePathWatcherFSEvents()
|
||||||
: objc_storage_(std::make_unique<ObjCStorage>()) {
|
: queue_(dispatch_queue_create(
|
||||||
objc_storage_->queue = dispatch_queue_create(
|
base::StringPrintf("org.chromium.base.FilePathWatcher.%p", this)
|
||||||
base::StringPrintf("org.chromium.base.FilePathWatcher.%p", this).c_str(),
|
.c_str(),
|
||||||
DISPATCH_QUEUE_SERIAL);
|
DISPATCH_QUEUE_SERIAL)) {}
|
||||||
}
|
|
||||||
|
|
||||||
FilePathWatcherFSEvents::~FilePathWatcherFSEvents() {
|
FilePathWatcherFSEvents::~FilePathWatcherFSEvents() {
|
||||||
DCHECK(!task_runner() || task_runner()->RunsTasksInCurrentSequence());
|
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
|
// This class could support non-recursive watches, but that is currently
|
||||||
// left to FilePathWatcherKQueue.
|
// left to FilePathWatcherKQueue.
|
||||||
if (type != Type::kRecursive) {
|
if (type != Type::kRecursive)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
set_task_runner(SequencedTaskRunner::GetCurrentDefault());
|
set_task_runner(SequencedTaskRunner::GetCurrentDefault());
|
||||||
callback_ = callback;
|
callback_ = callback;
|
||||||
@ -112,8 +99,8 @@ bool FilePathWatcherFSEvents::Watch(const FilePath& path,
|
|||||||
// captured by the block's scope.
|
// captured by the block's scope.
|
||||||
const FilePath path_copy(path);
|
const FilePath path_copy(path);
|
||||||
|
|
||||||
dispatch_async(objc_storage_->queue, ^{
|
dispatch_async(queue_, ^{
|
||||||
StartEventStream(start_event, path_copy);
|
StartEventStream(start_event, path_copy);
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -126,7 +113,7 @@ void FilePathWatcherFSEvents::Cancel() {
|
|||||||
// Switch to the dispatch queue to tear down the event stream. As the queue is
|
// 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
|
// owned by |this|, and this method is called from the destructor, execute the
|
||||||
// block synchronously.
|
// block synchronously.
|
||||||
dispatch_sync(objc_storage_->queue, ^{
|
dispatch_sync(queue_, ^{
|
||||||
if (fsevent_stream_) {
|
if (fsevent_stream_) {
|
||||||
DestroyEventStream();
|
DestroyEventStream();
|
||||||
target_.clear();
|
target_.clear();
|
||||||
@ -149,14 +136,12 @@ void FilePathWatcherFSEvents::FSEventsCallback(
|
|||||||
std::vector<FilePath> paths;
|
std::vector<FilePath> paths;
|
||||||
FSEventStreamEventId root_change_at = FSEventStreamGetLatestEventId(stream);
|
FSEventStreamEventId root_change_at = FSEventStreamGetLatestEventId(stream);
|
||||||
for (size_t i = 0; i < num_events; i++) {
|
for (size_t i = 0; i < num_events; i++) {
|
||||||
if (flags[i] & kFSEventStreamEventFlagRootChanged) {
|
if (flags[i] & kFSEventStreamEventFlagRootChanged)
|
||||||
root_changed = true;
|
root_changed = true;
|
||||||
}
|
if (event_ids[i])
|
||||||
if (event_ids[i]) {
|
|
||||||
root_change_at = std::min(root_change_at, event_ids[i]);
|
root_change_at = std::min(root_change_at, event_ids[i]);
|
||||||
}
|
paths.push_back(FilePath(
|
||||||
paths.push_back(FilePath(reinterpret_cast<char**>(event_paths)[i])
|
reinterpret_cast<char**>(event_paths)[i]).StripTrailingSeparators());
|
||||||
.StripTrailingSeparators());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reinitialize the event stream if we find changes to the root. This is
|
// Reinitialize the event stream if we find changes to the root. This is
|
||||||
@ -178,11 +163,10 @@ void FilePathWatcherFSEvents::FSEventsCallback(
|
|||||||
FROM_HERE, BindOnce(
|
FROM_HERE, BindOnce(
|
||||||
[](WeakPtr<FilePathWatcherFSEvents> weak_watcher,
|
[](WeakPtr<FilePathWatcherFSEvents> weak_watcher,
|
||||||
FSEventStreamEventId root_change_at) {
|
FSEventStreamEventId root_change_at) {
|
||||||
if (!weak_watcher) {
|
if (!weak_watcher)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
FilePathWatcherFSEvents* watcher = weak_watcher.get();
|
FilePathWatcherFSEvents* watcher = weak_watcher.get();
|
||||||
dispatch_async(watcher->objc_storage_->queue, ^{
|
dispatch_async(watcher->queue_, ^{
|
||||||
watcher->UpdateEventStream(root_change_at);
|
watcher->UpdateEventStream(root_change_at);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -223,35 +207,35 @@ void FilePathWatcherFSEvents::UpdateEventStream(
|
|||||||
FSEventStreamEventId start_event) {
|
FSEventStreamEventId start_event) {
|
||||||
// It can happen that the watcher gets canceled while tasks that call this
|
// 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.
|
// function are still in flight, so abort if this situation is detected.
|
||||||
if (resolved_target_.empty()) {
|
if (resolved_target_.empty())
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (fsevent_stream_) {
|
if (fsevent_stream_)
|
||||||
DestroyEventStream();
|
DestroyEventStream();
|
||||||
}
|
|
||||||
|
|
||||||
ScopedCFTypeRef<CFStringRef> cf_path(CFStringCreateWithCString(
|
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(
|
ScopedCFTypeRef<CFStringRef> cf_dir_path(CFStringCreateWithCString(
|
||||||
nullptr, resolved_target_.DirName().value().c_str(),
|
NULL, resolved_target_.DirName().value().c_str(),
|
||||||
kCFStringEncodingMacHFS));
|
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(
|
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));
|
std::size(paths_array), &kCFTypeArrayCallBacks));
|
||||||
|
|
||||||
FSEventStreamContext context;
|
FSEventStreamContext context;
|
||||||
context.version = 0;
|
context.version = 0;
|
||||||
context.info = this;
|
context.info = this;
|
||||||
context.retain = nullptr;
|
context.retain = NULL;
|
||||||
context.release = nullptr;
|
context.release = NULL;
|
||||||
context.copyDescription = nullptr;
|
context.copyDescription = NULL;
|
||||||
|
|
||||||
fsevent_stream_ = FSEventStreamCreate(
|
fsevent_stream_ = FSEventStreamCreate(NULL, &FSEventsCallback, &context,
|
||||||
nullptr, &FSEventsCallback, &context, watched_paths, start_event,
|
watched_paths,
|
||||||
kEventLatencySeconds, kFSEventStreamCreateFlagWatchRoot);
|
start_event,
|
||||||
FSEventStreamSetDispatchQueue(fsevent_stream_, objc_storage_->queue);
|
kEventLatencySeconds,
|
||||||
|
kFSEventStreamCreateFlagWatchRoot);
|
||||||
|
FSEventStreamSetDispatchQueue(fsevent_stream_, queue_);
|
||||||
|
|
||||||
if (!FSEventStreamStart(fsevent_stream_)) {
|
if (!FSEventStreamStart(fsevent_stream_)) {
|
||||||
task_runner()->PostTask(FROM_HERE,
|
task_runner()->PostTask(FROM_HERE,
|
||||||
@ -283,7 +267,7 @@ void FilePathWatcherFSEvents::DestroyEventStream() {
|
|||||||
FSEventStreamStop(fsevent_stream_);
|
FSEventStreamStop(fsevent_stream_);
|
||||||
FSEventStreamInvalidate(fsevent_stream_);
|
FSEventStreamInvalidate(fsevent_stream_);
|
||||||
FSEventStreamRelease(fsevent_stream_);
|
FSEventStreamRelease(fsevent_stream_);
|
||||||
fsevent_stream_ = nullptr;
|
fsevent_stream_ = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FilePathWatcherFSEvents::StartEventStream(FSEventStreamEventId start_event,
|
void FilePathWatcherFSEvents::StartEventStream(FSEventStreamEventId start_event,
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include "base/files/file_path.h"
|
#include "base/files/file_path.h"
|
||||||
#include "base/files/file_path_watcher.h"
|
#include "base/files/file_path_watcher.h"
|
||||||
|
#include "base/mac/scoped_dispatch_object.h"
|
||||||
#include "base/memory/weak_ptr.h"
|
#include "base/memory/weak_ptr.h"
|
||||||
|
|
||||||
namespace base {
|
namespace base {
|
||||||
@ -74,6 +75,9 @@ class FilePathWatcherFSEvents : public FilePathWatcher::PlatformDelegate {
|
|||||||
// (Only accessed from the task_runner() thread.)
|
// (Only accessed from the task_runner() thread.)
|
||||||
FilePathWatcher::Callback callback_;
|
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).
|
// Target path to watch (passed to callback).
|
||||||
// (Only accessed from the libdispatch queue.)
|
// (Only accessed from the libdispatch queue.)
|
||||||
FilePath target_;
|
FilePath target_;
|
||||||
@ -86,9 +90,6 @@ class FilePathWatcherFSEvents : public FilePathWatcher::PlatformDelegate {
|
|||||||
// (Only accessed from the libdispatch queue.)
|
// (Only accessed from the libdispatch queue.)
|
||||||
FSEventStreamRef fsevent_stream_ = nullptr;
|
FSEventStreamRef fsevent_stream_ = nullptr;
|
||||||
|
|
||||||
struct ObjCStorage;
|
|
||||||
std::unique_ptr<ObjCStorage> objc_storage_;
|
|
||||||
|
|
||||||
WeakPtrFactory<FilePathWatcherFSEvents> weak_factory_{this};
|
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 <dispatch/dispatch.h>
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "base/base_export.h"
|
#include "base/base_export.h"
|
||||||
|
#include "base/mac/scoped_dispatch_object.h"
|
||||||
|
|
||||||
namespace base {
|
namespace base {
|
||||||
|
|
||||||
@ -43,11 +42,17 @@ class BASE_EXPORT DispatchSourceMach {
|
|||||||
// be received.
|
// be received.
|
||||||
void Resume();
|
void Resume();
|
||||||
|
|
||||||
dispatch_queue_t queue() const;
|
dispatch_queue_t queue() const { return queue_.get(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct ObjCStorage;
|
// The dispatch queue used to service the source_.
|
||||||
std::unique_ptr<ObjCStorage> objc_storage_;
|
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
|
} // 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/notreached.h"
|
||||||
#include "base/strings/stringprintf.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)
|
#if BUILDFLAG(IS_IOS)
|
||||||
#include "base/ios/sim_header_shims.h"
|
#include "base/ios/sim_header_shims.h"
|
||||||
#else
|
#else
|
||||||
@ -107,19 +103,6 @@ void MachRendezvousPort::Destroy() {
|
|||||||
disposition_ = 0;
|
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
|
// static
|
||||||
MachPortRendezvousServer* MachPortRendezvousServer::GetInstance() {
|
MachPortRendezvousServer* MachPortRendezvousServer::GetInstance() {
|
||||||
static auto* instance = new MachPortRendezvousServer();
|
static auto* instance = new MachPortRendezvousServer();
|
||||||
@ -133,9 +116,9 @@ void MachPortRendezvousServer::RegisterPortsForPid(
|
|||||||
DCHECK_LT(ports.size(), kMaximumRendezvousPorts);
|
DCHECK_LT(ports.size(), kMaximumRendezvousPorts);
|
||||||
DCHECK(!ports.empty());
|
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_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, ^{
|
dispatch_source_set_event_handler(exit_watcher, ^{
|
||||||
OnClientExited(pid);
|
OnClientExited(pid);
|
||||||
});
|
});
|
||||||
@ -146,6 +129,15 @@ void MachPortRendezvousServer::RegisterPortsForPid(
|
|||||||
DCHECK(it.second);
|
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() {
|
MachPortRendezvousServer::MachPortRendezvousServer() {
|
||||||
std::string bootstrap_name =
|
std::string bootstrap_name =
|
||||||
StringPrintf(kBootstrapNameFormat, mac::BaseBundleID(), getpid());
|
StringPrintf(kBootstrapNameFormat, mac::BaseBundleID(), getpid());
|
||||||
@ -162,7 +154,7 @@ MachPortRendezvousServer::MachPortRendezvousServer() {
|
|||||||
dispatch_source_->Resume();
|
dispatch_source_->Resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
MachPortRendezvousServer::~MachPortRendezvousServer() = default;
|
MachPortRendezvousServer::~MachPortRendezvousServer() {}
|
||||||
|
|
||||||
void MachPortRendezvousServer::HandleRequest() {
|
void MachPortRendezvousServer::HandleRequest() {
|
||||||
// Receive the request message, using the kernel audit token to ascertain the
|
// Receive the request message, using the kernel audit token to ascertain the
|
||||||
@ -280,7 +272,8 @@ MachPortRendezvousClient* MachPortRendezvousClient::GetInstance() {
|
|||||||
client = nullptr;
|
client = nullptr;
|
||||||
}
|
}
|
||||||
return client;
|
return client;
|
||||||
}();
|
}
|
||||||
|
();
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include "base/base_export.h"
|
#include "base/base_export.h"
|
||||||
#include "base/mac/dispatch_source_mach.h"
|
#include "base/mac/dispatch_source_mach.h"
|
||||||
|
#include "base/mac/scoped_dispatch_object.h"
|
||||||
#include "base/mac/scoped_mach_port.h"
|
#include "base/mac/scoped_mach_port.h"
|
||||||
#include "base/synchronization/lock.h"
|
#include "base/synchronization/lock.h"
|
||||||
#include "base/thread_annotations.h"
|
#include "base/thread_annotations.h"
|
||||||
@ -107,6 +108,19 @@ class BASE_EXPORT MachPortRendezvousServer {
|
|||||||
friend class MachPortRendezvousServerTest;
|
friend class MachPortRendezvousServerTest;
|
||||||
friend struct MachPortRendezvousFuzzer;
|
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();
|
||||||
~MachPortRendezvousServer();
|
~MachPortRendezvousServer();
|
||||||
|
|
||||||
@ -138,7 +152,6 @@ class BASE_EXPORT MachPortRendezvousServer {
|
|||||||
// Mach message dispatch source for |server_port_|.
|
// Mach message dispatch source for |server_port_|.
|
||||||
std::unique_ptr<DispatchSourceMach> dispatch_source_;
|
std::unique_ptr<DispatchSourceMach> dispatch_source_;
|
||||||
|
|
||||||
struct ClientData;
|
|
||||||
Lock lock_;
|
Lock lock_;
|
||||||
// Association of pid-to-ports.
|
// Association of pid-to-ports.
|
||||||
std::map<pid_t, ClientData> client_data_ GUARDED_BY(lock_);
|
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)
|
#elif BUILDFLAG(IS_APPLE)
|
||||||
#include <dispatch/dispatch.h>
|
#include <dispatch/dispatch.h>
|
||||||
|
|
||||||
#include <memory>
|
#include "base/mac/scoped_dispatch_object.h"
|
||||||
|
|
||||||
#include "base/memory/weak_ptr.h"
|
#include "base/memory/weak_ptr.h"
|
||||||
#include "base/synchronization/waitable_event.h"
|
#include "base/synchronization/waitable_event.h"
|
||||||
#else
|
#else
|
||||||
@ -132,8 +131,10 @@ class BASE_EXPORT WaitableEventWatcher
|
|||||||
// is waiting. Null if no event is being watched.
|
// is waiting. Null if no event is being watched.
|
||||||
scoped_refptr<WaitableEvent::ReceiveRight> receive_right_;
|
scoped_refptr<WaitableEvent::ReceiveRight> receive_right_;
|
||||||
|
|
||||||
struct ObjCStorage;
|
// A TYPE_MACH_RECV dispatch source on |receive_right_|. When a receive event
|
||||||
std::unique_ptr<ObjCStorage> objc_storage_;
|
// 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
|
// Used to vend a weak pointer for calling InvokeCallback() from the
|
||||||
// |source_| event handler.
|
// |source_| event handler.
|
||||||
|
@ -7,21 +7,9 @@
|
|||||||
#include "base/functional/bind.h"
|
#include "base/functional/bind.h"
|
||||||
#include "base/functional/callback.h"
|
#include "base/functional/callback.h"
|
||||||
|
|
||||||
#if !defined(__has_feature) || !__has_feature(objc_arc)
|
|
||||||
#error "This file requires ARC support."
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace base {
|
namespace base {
|
||||||
|
|
||||||
struct WaitableEventWatcher::ObjCStorage {
|
WaitableEventWatcher::WaitableEventWatcher() : weak_ptr_factory_(this) {}
|
||||||
// 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() {
|
WaitableEventWatcher::~WaitableEventWatcher() {
|
||||||
StopWatching();
|
StopWatching();
|
||||||
@ -32,8 +20,7 @@ bool WaitableEventWatcher::StartWatching(
|
|||||||
EventCallback callback,
|
EventCallback callback,
|
||||||
scoped_refptr<SequencedTaskRunner> task_runner) {
|
scoped_refptr<SequencedTaskRunner> task_runner) {
|
||||||
DCHECK(task_runner->RunsTasksInCurrentSequence());
|
DCHECK(task_runner->RunsTasksInCurrentSequence());
|
||||||
DCHECK(!objc_storage_->source ||
|
DCHECK(!source_ || dispatch_source_testcancel(source_));
|
||||||
dispatch_source_testcancel(objc_storage_->source));
|
|
||||||
|
|
||||||
// Keep a reference to the receive right, so that if the event is deleted
|
// 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.
|
// 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
|
// Use the global concurrent queue here, since it is only used to thunk
|
||||||
// to the real callback on the target task runner.
|
// to the real callback on the target task runner.
|
||||||
objc_storage_->source = dispatch_source_create(
|
source_.reset(dispatch_source_create(
|
||||||
DISPATCH_SOURCE_TYPE_MACH_RECV, receive_right_->Name(), /*mask=*/0,
|
DISPATCH_SOURCE_TYPE_MACH_RECV, receive_right_->Name(), 0,
|
||||||
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, /*flags=*/0));
|
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)));
|
||||||
|
|
||||||
// Locals for capture by the block. Accessing anything through the |this| or
|
// 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
|
// |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();
|
WeakPtr<WaitableEventWatcher> weak_this = weak_ptr_factory_.GetWeakPtr();
|
||||||
const bool auto_reset =
|
const bool auto_reset =
|
||||||
event->policy_ == WaitableEvent::ResetPolicy::AUTOMATIC;
|
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();
|
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
|
// For automatic-reset events, only fire the callback if this watcher
|
||||||
// can claim/dequeue the event. For manual-reset events, all watchers can
|
// can claim/dequeue the event. For manual-reset events, all watchers can
|
||||||
// be called back.
|
// be called back.
|
||||||
@ -71,7 +58,7 @@ bool WaitableEventWatcher::StartWatching(
|
|||||||
task_runner->PostTask(
|
task_runner->PostTask(
|
||||||
FROM_HERE, BindOnce(&WaitableEventWatcher::InvokeCallback, weak_this));
|
FROM_HERE, BindOnce(&WaitableEventWatcher::InvokeCallback, weak_this));
|
||||||
});
|
});
|
||||||
dispatch_resume(objc_storage_->source);
|
dispatch_resume(source_);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -79,19 +66,18 @@ bool WaitableEventWatcher::StartWatching(
|
|||||||
void WaitableEventWatcher::StopWatching() {
|
void WaitableEventWatcher::StopWatching() {
|
||||||
callback_.Reset();
|
callback_.Reset();
|
||||||
receive_right_ = nullptr;
|
receive_right_ = nullptr;
|
||||||
if (objc_storage_->source) {
|
if (source_) {
|
||||||
dispatch_source_cancel(objc_storage_->source);
|
dispatch_source_cancel(source_);
|
||||||
objc_storage_->source = nil;
|
source_.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaitableEventWatcher::InvokeCallback() {
|
void WaitableEventWatcher::InvokeCallback() {
|
||||||
// The callback can be null if StopWatching() is called between signaling
|
// The callback can be null if StopWatching() is called between signaling
|
||||||
// and the |callback_| getting run on the target task runner.
|
// and the |callback_| getting run on the target task runner.
|
||||||
if (callback_.is_null()) {
|
if (callback_.is_null())
|
||||||
return;
|
return;
|
||||||
}
|
source_.reset();
|
||||||
objc_storage_->source = nil;
|
|
||||||
receive_right_ = nullptr;
|
receive_right_ = nullptr;
|
||||||
std::move(callback_).Run();
|
std::move(callback_).Run();
|
||||||
}
|
}
|
@ -30,10 +30,9 @@ source_set("memory_pressure") {
|
|||||||
|
|
||||||
if (is_apple) {
|
if (is_apple) {
|
||||||
sources += [
|
sources += [
|
||||||
|
"system_memory_pressure_evaluator_mac.cc",
|
||||||
"system_memory_pressure_evaluator_mac.h",
|
"system_memory_pressure_evaluator_mac.h",
|
||||||
"system_memory_pressure_evaluator_mac.mm",
|
|
||||||
]
|
]
|
||||||
configs += [ "//build/config/compiler:enable_arc" ]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_fuchsia) {
|
if (is_fuchsia) {
|
||||||
|
@ -19,10 +19,6 @@
|
|||||||
#include "base/memory/memory_pressure_monitor.h"
|
#include "base/memory/memory_pressure_monitor.h"
|
||||||
#include "base/task/sequenced_task_runner.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 memory_pressure::mac {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -47,28 +43,22 @@ SystemMemoryPressureEvaluator::MemoryPressureLevelForMacMemoryPressureLevel(
|
|||||||
return base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
|
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(
|
SystemMemoryPressureEvaluator::SystemMemoryPressureEvaluator(
|
||||||
std::unique_ptr<MemoryPressureVoter> voter)
|
std::unique_ptr<MemoryPressureVoter> voter)
|
||||||
: memory_pressure::SystemMemoryPressureEvaluator(std::move(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_(
|
renotify_current_vote_timer_(
|
||||||
FROM_HERE,
|
FROM_HERE,
|
||||||
kRenotifyVotePeriod,
|
kRenotifyVotePeriod,
|
||||||
base::BindRepeating(&SystemMemoryPressureEvaluator::SendCurrentVote,
|
base::BindRepeating(&SystemMemoryPressureEvaluator::SendCurrentVote,
|
||||||
base::Unretained(this),
|
base::Unretained(this),
|
||||||
/*notify=*/true)),
|
/*notify=*/true)),
|
||||||
objc_storage_(std::make_unique<ObjCStorage>()),
|
|
||||||
weak_ptr_factory_(this) {
|
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
|
// WeakPtr needed because there is no guarantee that |this| is still be alive
|
||||||
// when the task posted to the TaskRunner or event handler runs.
|
// when the task posted to the TaskRunner or event handler runs.
|
||||||
base::WeakPtr<SystemMemoryPressureEvaluator> weak_this =
|
base::WeakPtr<SystemMemoryPressureEvaluator> weak_this =
|
||||||
@ -77,25 +67,24 @@ SystemMemoryPressureEvaluator::SystemMemoryPressureEvaluator(
|
|||||||
base::SequencedTaskRunner::GetCurrentDefault();
|
base::SequencedTaskRunner::GetCurrentDefault();
|
||||||
|
|
||||||
// Attach an event handler to the memory pressure event source.
|
// Attach an event handler to the memory pressure event source.
|
||||||
if (objc_storage_->memory_level_event_source) {
|
if (memory_level_event_source_.get()) {
|
||||||
dispatch_source_set_event_handler(
|
dispatch_source_set_event_handler(memory_level_event_source_, ^{
|
||||||
objc_storage_->memory_level_event_source, ^{
|
task_runner->PostTask(
|
||||||
task_runner->PostTask(
|
FROM_HERE,
|
||||||
FROM_HERE,
|
base::BindRepeating(
|
||||||
base::BindRepeating(
|
&SystemMemoryPressureEvaluator::OnMemoryPressureChanged,
|
||||||
&SystemMemoryPressureEvaluator::OnMemoryPressureChanged,
|
weak_this));
|
||||||
weak_this));
|
});
|
||||||
});
|
|
||||||
|
|
||||||
// Start monitoring the event source.
|
// Start monitoring the event source.
|
||||||
dispatch_resume(objc_storage_->memory_level_event_source);
|
dispatch_resume(memory_level_event_source_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemMemoryPressureEvaluator::~SystemMemoryPressureEvaluator() {
|
SystemMemoryPressureEvaluator::~SystemMemoryPressureEvaluator() {
|
||||||
// Remove the memory pressure event source.
|
// Remove the memory pressure event source.
|
||||||
if (objc_storage_->memory_level_event_source) {
|
if (memory_level_event_source_.get()) {
|
||||||
dispatch_source_cancel(objc_storage_->memory_level_event_source);
|
dispatch_source_cancel(memory_level_event_source_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,7 +115,7 @@ void SystemMemoryPressureEvaluator::OnMemoryPressureChanged() {
|
|||||||
UpdatePressureLevel();
|
UpdatePressureLevel();
|
||||||
|
|
||||||
// Run the callback that's waiting on memory pressure change notifications.
|
// 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.
|
// normal.
|
||||||
bool notify = current_vote() !=
|
bool notify = current_vote() !=
|
||||||
base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
|
base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
|
@ -9,13 +9,15 @@
|
|||||||
#include <dispatch/dispatch.h>
|
#include <dispatch/dispatch.h>
|
||||||
|
|
||||||
#include "base/mac/scoped_cftyperef.h"
|
#include "base/mac/scoped_cftyperef.h"
|
||||||
|
#include "base/mac/scoped_dispatch_object.h"
|
||||||
#include "base/message_loop/message_pump_mac.h"
|
#include "base/message_loop/message_pump_mac.h"
|
||||||
#include "base/sequence_checker.h"
|
#include "base/sequence_checker.h"
|
||||||
#include "base/timer/timer.h"
|
#include "base/timer/timer.h"
|
||||||
#include "components/memory_pressure/memory_pressure_voter.h"
|
#include "components/memory_pressure/memory_pressure_voter.h"
|
||||||
#include "components/memory_pressure/system_memory_pressure_evaluator.h"
|
#include "components/memory_pressure/system_memory_pressure_evaluator.h"
|
||||||
|
|
||||||
namespace memory_pressure::mac {
|
namespace memory_pressure {
|
||||||
|
namespace mac {
|
||||||
|
|
||||||
class TestSystemMemoryPressureEvaluator;
|
class TestSystemMemoryPressureEvaluator;
|
||||||
|
|
||||||
@ -48,17 +50,18 @@ class SystemMemoryPressureEvaluator
|
|||||||
// Run |dispatch_callback| on memory pressure notifications from the OS.
|
// Run |dispatch_callback| on memory pressure notifications from the OS.
|
||||||
void OnMemoryPressureChanged();
|
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.
|
// Timer that will re-notify with the current vote at regular interval.
|
||||||
base::RepeatingTimer renotify_current_vote_timer_;
|
base::RepeatingTimer renotify_current_vote_timer_;
|
||||||
|
|
||||||
struct ObjCStorage;
|
|
||||||
std::unique_ptr<ObjCStorage> objc_storage_;
|
|
||||||
|
|
||||||
SEQUENCE_CHECKER(sequence_checker_);
|
SEQUENCE_CHECKER(sequence_checker_);
|
||||||
|
|
||||||
base::WeakPtrFactory<SystemMemoryPressureEvaluator> weak_ptr_factory_;
|
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_
|
#endif // COMPONENTS_MEMORY_PRESSURE_SYSTEM_MEMORY_PRESSURE_EVALUATOR_MAC_H_
|
||||||
|
@ -41,10 +41,6 @@ if (enable_nacl) {
|
|||||||
"//native_client/src/trusted/error_code",
|
"//native_client/src/trusted/error_code",
|
||||||
"//services/service_manager/public/cpp",
|
"//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
|
# 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" ]
|
sources += [ "named_mojo_server_endpoint_connector_win.cc" ]
|
||||||
} else if (is_mac) {
|
} else if (is_mac) {
|
||||||
sources += [ "named_mojo_server_endpoint_connector_mac.cc" ]
|
sources += [ "named_mojo_server_endpoint_connector_mac.cc" ]
|
||||||
deps += [ "//base:base_arc" ]
|
|
||||||
} else {
|
} else {
|
||||||
sources += [ "named_mojo_server_endpoint_connector_unsupported.cc" ]
|
sources += [ "named_mojo_server_endpoint_connector_unsupported.cc" ]
|
||||||
}
|
}
|
||||||
|
@ -142,10 +142,6 @@ target(link_target_type, "child") {
|
|||||||
libs = [ "dwrite.lib" ]
|
libs = [ "dwrite.lib" ]
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_apple) {
|
|
||||||
deps += [ "//base:base_arc" ]
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_mac) {
|
if (is_mac) {
|
||||||
sources += [
|
sources += [
|
||||||
"child_process_sandbox_support_impl_mac.cc",
|
"child_process_sandbox_support_impl_mac.cc",
|
||||||
|
@ -99,9 +99,7 @@ component("ipc") {
|
|||||||
"//services/tracing/public/cpp",
|
"//services/tracing/public/cpp",
|
||||||
]
|
]
|
||||||
|
|
||||||
if (is_apple) {
|
deps = [ "//base" ]
|
||||||
public_deps += [ "//base:base_arc" ]
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enable_ipc_fuzzer) {
|
if (enable_ipc_fuzzer) {
|
||||||
public_configs = [ "//tools/ipc_fuzzer:ipc_fuzzer_config" ]
|
public_configs = [ "//tools/ipc_fuzzer:ipc_fuzzer_config" ]
|
||||||
|
@ -58,10 +58,6 @@ component("platform") {
|
|||||||
deps += [ "//net" ]
|
deps += [ "//net" ]
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_apple) {
|
|
||||||
public_deps += [ "//base:base_arc" ]
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_mac) {
|
if (is_mac) {
|
||||||
sources += [ "named_platform_channel_mac.cc" ]
|
sources += [ "named_platform_channel_mac.cc" ]
|
||||||
}
|
}
|
||||||
|
@ -65,10 +65,6 @@ source_set("service_manager") {
|
|||||||
"//mojo/core/embedder",
|
"//mojo/core/embedder",
|
||||||
"//services/service_manager/public/cpp/service_executable:switches",
|
"//services/service_manager/public/cpp/service_executable:switches",
|
||||||
]
|
]
|
||||||
|
|
||||||
if (is_mac) {
|
|
||||||
public_deps += [ "//base:base_arc" ]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_linux || is_chromeos) {
|
if (is_linux || is_chromeos) {
|
||||||
|
@ -176,7 +176,6 @@ blink_platform_sources("loader") {
|
|||||||
deps = [
|
deps = [
|
||||||
":make_platform_loader_generated_delivery_type_names",
|
":make_platform_loader_generated_delivery_type_names",
|
||||||
":make_platform_loader_generated_fetch_initiator_type_names",
|
":make_platform_loader_generated_fetch_initiator_type_names",
|
||||||
"//base",
|
|
||||||
"//components/link_header_util",
|
"//components/link_header_util",
|
||||||
"//components/variations/net:net",
|
"//components/variations/net:net",
|
||||||
"//net",
|
"//net",
|
||||||
@ -198,10 +197,6 @@ blink_platform_sources("loader") {
|
|||||||
]
|
]
|
||||||
allow_circular_includes_from =
|
allow_circular_includes_from =
|
||||||
[ "//third_party/blink/renderer/platform/network:network" ]
|
[ "//third_party/blink/renderer/platform/network:network" ]
|
||||||
|
|
||||||
if (is_apple) {
|
|
||||||
deps += [ "//base:base_arc" ]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
source_set("unit_tests") {
|
source_set("unit_tests") {
|
||||||
|
Reference in New Issue
Block a user