diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-08-28 15:28:34 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-08-28 13:54:51 +0000 |
commit | 2a19c63448c84c1805fb1a585c3651318bb86ca7 (patch) | |
tree | eb17888e8531aa6ee5e85721bd553b832a7e5156 /chromium/base/bind_internal.h | |
parent | b014812705fc80bff0a5c120dfcef88f349816dc (diff) |
BASELINE: Update Chromium to 69.0.3497.70
Change-Id: I2b7b56e4e7a8b26656930def0d4575dc32b900a0
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/base/bind_internal.h')
-rw-r--r-- | chromium/base/bind_internal.h | 65 |
1 files changed, 62 insertions, 3 deletions
diff --git a/chromium/base/bind_internal.h b/chromium/base/bind_internal.h index d748f89f834..4ebecfaf771 100644 --- a/chromium/base/bind_internal.h +++ b/chromium/base/bind_internal.h @@ -11,11 +11,16 @@ #include <utility> #include "base/callback_internal.h" +#include "base/compiler_specific.h" #include "base/memory/raw_scoped_refptr_mismatch_checker.h" #include "base/memory/weak_ptr.h" #include "base/template_util.h" #include "build/build_config.h" +#if defined(OS_MACOSX) && !HAS_FEATURE(objc_arc) +#include "base/mac/scoped_block.h" +#endif + // See base/callback.h for user documentation. // // @@ -433,6 +438,61 @@ struct FunctorTraits<R(__fastcall*)(Args...)> { #endif // defined(OS_WIN) && !defined(ARCH_CPU_X86_64) +#if defined(OS_MACOSX) + +// Support for Objective-C blocks. There are two implementation depending +// on whether Automated Reference Counting (ARC) is enabled. When ARC is +// enabled, then the block itself can be bound as the compiler will ensure +// its lifetime will be correctly managed. Otherwise, require the block to +// be wrapped in a base::mac::ScopedBlock (via base::RetainBlock) that will +// correctly manage the block lifetime. +// +// The two implementation ensure that the One Definition Rule (ODR) is not +// broken (it is not possible to write a template base::RetainBlock that would +// work correctly both with ARC enabled and disabled). + +#if HAS_FEATURE(objc_arc) + +template <typename R, typename... Args> +struct FunctorTraits<R (^)(Args...)> { + using RunType = R(Args...); + static constexpr bool is_method = false; + static constexpr bool is_nullable = true; + + template <typename BlockType, typename... RunArgs> + static R Invoke(BlockType&& block, RunArgs&&... args) { + // According to LLVM documentation (ยง 6.3), "local variables of automatic + // storage duration do not have precise lifetime." Use objc_precise_lifetime + // to ensure that the Objective-C block is not deallocated until it has + // finished executing even if the Callback<> is destroyed during the block + // execution. + // https://clang.llvm.org/docs/AutomaticReferenceCounting.html#precise-lifetime-semantics + __attribute__((objc_precise_lifetime)) R (^scoped_block)(Args...) = block; + return scoped_block(std::forward<RunArgs>(args)...); + } +}; + +#else // HAS_FEATURE(objc_arc) + +template <typename R, typename... Args> +struct FunctorTraits<base::mac::ScopedBlock<R (^)(Args...)>> { + using RunType = R(Args...); + static constexpr bool is_method = false; + static constexpr bool is_nullable = true; + + template <typename BlockType, typename... RunArgs> + static R Invoke(BlockType&& block, RunArgs&&... args) { + // Copy the block to ensure that the Objective-C block is not deallocated + // until it has finished executing even if the Callback<> is destroyed + // during the block execution. + base::mac::ScopedBlock<R (^)(Args...)> scoped_block(block); + return scoped_block.get()(std::forward<RunArgs>(args)...); + } +}; + +#endif // HAS_FEATURE(objc_arc) +#endif // defined(OS_MACOSX) + // For methods. template <typename R, typename Receiver, typename... Args> struct FunctorTraits<R (Receiver::*)(Args...)> { @@ -579,7 +639,7 @@ struct Invoker; template <typename StorageType, typename R, typename... UnboundArgs> struct Invoker<StorageType, R(UnboundArgs...)> { static R RunOnce(BindStateBase* base, - PassingTraitsType<UnboundArgs>... unbound_args) { + PassingType<UnboundArgs>... unbound_args) { // Local references to make debugger stepping easier. If in a debugger, // you really want to warp ahead and step through the // InvokeHelper<>::MakeItSo() call below. @@ -592,8 +652,7 @@ struct Invoker<StorageType, R(UnboundArgs...)> { std::forward<UnboundArgs>(unbound_args)...); } - static R Run(BindStateBase* base, - PassingTraitsType<UnboundArgs>... unbound_args) { + static R Run(BindStateBase* base, PassingType<UnboundArgs>... unbound_args) { // Local references to make debugger stepping easier. If in a debugger, // you really want to warp ahead and step through the // InvokeHelper<>::MakeItSo() call below. |