Skip to content

Commit

Permalink
Revert "Convert Mac MessagePumps to use ARC"
Browse files Browse the repository at this point in the history
This reverts commit 89d2b7a.

Reason for revert: https://crbug.com/1451668

Original change's description:
> Convert Mac MessagePumps to use ARC
>
> See https://chromium.googlesource.com/chromium/src/+/main/docs/mac/arc.md
> for information about this conversion.
>
> Bug: 1280317
> Change-Id: Ieed0882e35a1a5666bb1e981bf96e5cc99d44f8d
> Cq-Include-Trybots: luci.chromium.try:ios-blink-dbg-fyi
> Cq-Include-Trybots: luci.chrome.try:mac-chrome
> Validate-Test-Flakiness: skip
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4582569
> Auto-Submit: 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@{#1152742}

Bug: 1280317
Change-Id: I55621483d77a6b5cf93f8ff0dd5ca47edeffaafa
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4594714
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Reviewed-by: Mark Mentovai <mark@chromium.org>
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Auto-Submit: Avi Drissman <avi@chromium.org>
Commit-Queue: Avi Drissman <avi@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1153976}
  • Loading branch information
Avi Drissman authored and Chromium LUCI CQ committed Jun 6, 2023
1 parent 8e25b58 commit 9dbb9ba
Show file tree
Hide file tree
Showing 10 changed files with 218 additions and 191 deletions.
4 changes: 2 additions & 2 deletions base/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,6 @@ if (is_apple) {
sources = [
"apple/owned_objc.h",
"apple/owned_objc.mm",
"message_loop/message_pump_mac.h",
"message_loop/message_pump_mac.mm",
]
if (is_mac) {
sources += [
Expand Down Expand Up @@ -2111,6 +2109,8 @@ component("base") {
"mac/scoped_typeref.h",
"memory/platform_shared_memory_mapper_mac.cc",
"memory/platform_shared_memory_region_mac.cc",
"message_loop/message_pump_mac.h",
"message_loop/message_pump_mac.mm",
"process/process_metrics_apple_internal.cc",
"process/process_metrics_apple_internal.h",
"profiler/module_cache_mac.cc",
Expand Down
2 changes: 1 addition & 1 deletion base/message_loop/message_pump.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ std::unique_ptr<MessagePump> MessagePump::Create(MessagePumpType type) {
if (message_pump_for_ui_factory_)
return message_pump_for_ui_factory_();
#if BUILDFLAG(IS_APPLE)
return message_pump_mac::Create();
return MessagePumpMac::Create();
#elif BUILDFLAG(IS_NACL) || BUILDFLAG(IS_AIX)
// Currently NaCl and AIX don't have a UI MessagePump.
// TODO(abarth): Figure out if we need this.
Expand Down
4 changes: 2 additions & 2 deletions base/message_loop/message_pump_for_ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ using MessagePumpForUI = MessagePumpForUI;
using MessagePumpForUI = MessagePumpForUI;
#elif BUILDFLAG(IS_APPLE)
// MessagePumpForUI isn't bound to a specific impl on Mac. While each impl can
// be represented by a plain MessagePump: message_pump_mac::Create() must be
// used to instantiate the right impl.
// be represented by a plain MessagePump: MessagePumpMac::Create() must be used
// to instantiate the right impl.
using MessagePumpForUI = MessagePump;
#elif BUILDFLAG(IS_NACL) || BUILDFLAG(IS_AIX)
// Currently NaCl and AIX don't have a MessagePumpForUI.
Expand Down
119 changes: 69 additions & 50 deletions base/message_loop/message_pump_mac.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,22 @@
// Typically, MessagePumpNSApplication only makes sense on a Cocoa
// application's main thread. If a CFRunLoop-based message pump is needed on
// any other thread, one of the other concrete subclasses is preferable.
// message_pump_mac::Create is defined, which returns a new NSApplication-based
// MessagePumpMac::Create is defined, which returns a new NSApplication-based
// or NSRunLoop-based MessagePump subclass depending on which thread it is
// called on.

#ifndef BASE_MESSAGE_LOOP_MESSAGE_PUMP_MAC_H_
#define BASE_MESSAGE_LOOP_MESSAGE_PUMP_MAC_H_

#include "base/memory/raw_ptr.h"
#include "base/message_loop/message_pump.h"

#include <CoreFoundation/CoreFoundation.h>

#include <CoreFoundation/CoreFoundation.h>
#include <memory>

#include "base/containers/stack.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/memory/raw_ptr.h"
#include "base/message_loop/timer_slack.h"
#include "base/run_loop.h"
#include "build/build_config.h"
#include "third_party/abseil-cpp/absl/types/optional.h"

Expand All @@ -63,6 +61,24 @@

namespace base {

class RunLoop;

// AutoreleasePoolType is a proxy type for autorelease pools. Its definition
// depends on the translation unit (TU) in which this header appears. In pure
// C++ TUs, it is defined as a forward C++ class declaration (that is never
// defined), because autorelease pools are an Objective-C concept. In Automatic
// Reference Counting (ARC) Objective-C TUs, it is similarly defined as a
// forward C++ class declaration, because clang will not allow the type
// "NSAutoreleasePool" in such TUs. Finally, in Manual Retain Release (MRR)
// Objective-C TUs, it is a type alias for NSAutoreleasePool. In all cases, a
// method that takes or returns an NSAutoreleasePool* can use
// AutoreleasePoolType* instead.
#if !defined(__OBJC__) || __has_feature(objc_arc)
class AutoreleasePoolType;
#else // !defined(__OBJC__) || __has_feature(objc_arc)
typedef NSAutoreleasePool AutoreleasePoolType;
#endif // !defined(__OBJC__) || __has_feature(objc_arc)

class BASE_EXPORT MessagePumpCFRunLoopBase : public MessagePump {
public:
MessagePumpCFRunLoopBase(const MessagePumpCFRunLoopBase&) = delete;
Expand All @@ -89,7 +105,7 @@ class BASE_EXPORT MessagePumpCFRunLoopBase : public MessagePump {

protected:
// Needs access to CreateAutoreleasePool.
friend class OptionalAutoreleasePool;
friend class MessagePumpScopedAutoreleasePool;
friend class TestMessagePumpCFRunLoopBase;

// Tasks will be pumped in the run loop modes described by
Expand Down Expand Up @@ -128,11 +144,11 @@ class BASE_EXPORT MessagePumpCFRunLoopBase : public MessagePump {
// |delegateless_work_| is true. |delegate| can be NULL.
void SetDelegate(Delegate* delegate);

// Return whether an autorelease pool should be created to wrap around any
// work being performed. If false is returned to prevent an autorelease pool
// from being created, any objects autoreleased by work will fall into the
// current autorelease pool.
virtual bool ShouldCreateAutoreleasePool();
// Return an autorelease pool to wrap around any work being performed.
// In some cases, CreateAutoreleasePool may return nil intentionally to
// preventing an autorelease pool from being created, allowing any
// objects autoreleased by work to fall into the current autorelease pool.
virtual AutoreleasePoolType* CreateAutoreleasePool();

// Enable and disable entries in |enabled_modes_| to match |mode_mask|.
void SetModeMask(int mode_mask);
Expand Down Expand Up @@ -215,52 +231,52 @@ class BASE_EXPORT MessagePumpCFRunLoopBase : public MessagePump {
void PushWorkItemScope();

// The thread's run loop.
base::ScopedCFTypeRef<CFRunLoopRef> run_loop_;
CFRunLoopRef run_loop_;

// The enabled modes. Posted tasks may run in any non-null entry.
std::unique_ptr<ScopedModeEnabler> enabled_modes_[kNumModes];

// The timer, sources, and observers are described above alongside their
// callbacks.
base::ScopedCFTypeRef<CFRunLoopTimerRef> delayed_work_timer_;
base::ScopedCFTypeRef<CFRunLoopSourceRef> work_source_;
base::ScopedCFTypeRef<CFRunLoopSourceRef> nesting_deferred_work_source_;
base::ScopedCFTypeRef<CFRunLoopObserverRef> pre_wait_observer_;
base::ScopedCFTypeRef<CFRunLoopObserverRef> after_wait_observer_;
base::ScopedCFTypeRef<CFRunLoopObserverRef> pre_source_observer_;
base::ScopedCFTypeRef<CFRunLoopObserverRef> enter_exit_observer_;
CFRunLoopTimerRef delayed_work_timer_;
CFRunLoopSourceRef work_source_;
CFRunLoopSourceRef nesting_deferred_work_source_;
CFRunLoopObserverRef pre_wait_observer_;
CFRunLoopObserverRef after_wait_observer_;
CFRunLoopObserverRef pre_source_observer_;
CFRunLoopObserverRef enter_exit_observer_;

// (weak) Delegate passed as an argument to the innermost Run call.
raw_ptr<Delegate> delegate_ = nullptr;
raw_ptr<Delegate> delegate_;

base::TimerSlack timer_slack_ = base::TIMER_SLACK_NONE;
base::TimerSlack timer_slack_;

// Time at which `delayed_work_timer_` is set to fire.
base::TimeTicks delayed_work_scheduled_at_ = base::TimeTicks::Max();

// The recursion depth of the currently-executing CFRunLoopRun loop on the
// run loop's thread. 0 if no run loops are running inside of whatever scope
// the object was created in.
int nesting_level_ = 0;
int nesting_level_;

// The recursion depth (calculated in the same way as |nesting_level_|) of the
// innermost executing CFRunLoopRun loop started by a call to Run.
int run_nesting_level_ = 0;
int run_nesting_level_;

// The deepest (numerically highest) recursion depth encountered since the
// most recent attempt to run nesting-deferred work.
int deepest_nesting_level_ = 0;
int deepest_nesting_level_;

// Whether we should continue running application tasks. Set to false when
// Quit() is called for the innermost run loop.
bool keep_running_ = true;
bool keep_running_;

// "Delegateless" work flags are set when work is ready to be performed but
// must wait until a delegate is available to process it. This can happen
// when a MessagePumpCFRunLoopBase is instantiated and work arrives without
// any call to Run on the stack. The Run method will check for delegateless
// work on entry and redispatch it as needed once a delegate is available.
bool delegateless_work_ = false;
bool delegateless_work_;

// Used to keep track of the native event work items processed by the message
// pump. Made of optionals because tracking can be suspended when it's
Expand Down Expand Up @@ -308,7 +324,7 @@ class BASE_EXPORT MessagePumpNSRunLoop : public MessagePumpCFRunLoopBase {
// A source that doesn't do anything but provide something signalable
// attached to the run loop. This source will be signalled when Quit
// is called, to cause the loop to wake up so that it can stop.
base::ScopedCFTypeRef<CFRunLoopSourceRef> quit_source_;
CFRunLoopSourceRef quit_source_;
};

#if BUILDFLAG(IS_IOS)
Expand All @@ -334,7 +350,7 @@ class MessagePumpUIApplication : public MessagePumpCFRunLoopBase {
void Detach() override;

private:
absl::optional<RunLoop> run_loop_;
RunLoop* run_loop_;
};

#else
Expand Down Expand Up @@ -376,11 +392,11 @@ class MessagePumpNSApplication : public MessagePumpCFRunLoopBase {
// -[NSApplication run] handle it. The outermost run loop in the application
// is managed by -[NSApplication run], inner run loops are handled by a loop
// in DoRun.
bool running_own_loop_ = false;
bool running_own_loop_;

// True if Quit() was called while a modal window was shown and needed to be
// deferred.
bool quit_pending_ = false;
bool quit_pending_;
};

class MessagePumpCrApplication : public MessagePumpNSApplication {
Expand All @@ -393,38 +409,41 @@ class MessagePumpCrApplication : public MessagePumpNSApplication {
~MessagePumpCrApplication() override;

protected:
// Returns false if NSApp is currently in the middle of calling -sendEvent.
// Requires NSApp implementing CrAppProtocol.
bool ShouldCreateAutoreleasePool() override;
// Returns nil if NSApp is currently in the middle of calling
// -sendEvent. Requires NSApp implementing CrAppProtocol.
AutoreleasePoolType* CreateAutoreleasePool() override;
};
#endif // BUILDFLAG(IS_IOS)

namespace message_pump_mac {

// If not on the main thread, returns a new instance of
// MessagePumpNSRunLoop.
//
// On the main thread, if NSApp exists and conforms to
// CrAppProtocol, creates an instances of MessagePumpCrApplication.
//
// Otherwise creates an instance of MessagePumpNSApplication using a
// default NSApplication.
BASE_EXPORT std::unique_ptr<MessagePump> Create();
class BASE_EXPORT MessagePumpMac {
public:
MessagePumpMac() = delete;
MessagePumpMac(const MessagePumpMac&) = delete;
MessagePumpMac& operator=(const MessagePumpMac&) = delete;

// If not on the main thread, returns a new instance of
// MessagePumpNSRunLoop.
//
// On the main thread, if NSApp exists and conforms to
// CrAppProtocol, creates an instances of MessagePumpCrApplication.
//
// Otherwise creates an instance of MessagePumpNSApplication using a
// default NSApplication.
static std::unique_ptr<MessagePump> Create();

#if !BUILDFLAG(IS_IOS)
// If a pump is created before the required CrAppProtocol is
// created, the wrong MessagePump subclass could be used.
// UsingCrApp() returns false if the message pump was created before
// NSApp was initialized, or if NSApp does not implement
// CrAppProtocol. NSApp must be initialized before calling.
BASE_EXPORT bool UsingCrApp();
static bool UsingCrApp();

// Wrapper to query -[NSApp isHandlingSendEvent] from C++ code.
// Requires NSApp to implement CrAppProtocol.
BASE_EXPORT bool IsHandlingSendEvent();
// Wrapper to query -[NSApp isHandlingSendEvent] from C++ code.
// Requires NSApp to implement CrAppProtocol.
static bool IsHandlingSendEvent();
#endif // !BUILDFLAG(IS_IOS)

} // namespace message_pump_mac
};

// Tasks posted to the message loop are posted under this mode, as well
// as kCFRunLoopCommonModes.
Expand Down

0 comments on commit 9dbb9ba

Please sign in to comment.