diff --git a/base/BUILD.gn b/base/BUILD.gn index 4bec3407bfbe6bee242ce696be893c70d044bc6c..4778c4402821cc6e22f75b3606266537b8ec907e 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn @@ -25,8 +25,12 @@ declare_args() { config("utils_config") { include_dirs = [ "include" ] + defines = [] if (current_os == "ios") { - defines = [ "IOS_PLATFORM" ] + defines += [ "IOS_PLATFORM" ] + } + if (is_emulator == true) { + defines += [ "EMULATOR_PLATFORM" ] } } diff --git a/base/include/refbase.h b/base/include/refbase.h index 7fcbef7f2e520125746ac993476cb947c176c047..af3f6d6c8d83ea623646d59667108dee9269e832 100644 --- a/base/include/refbase.h +++ b/base/include/refbase.h @@ -240,6 +240,16 @@ public: */ void ExtendObjectLifetime(); +#ifndef EMULATOR_PLATFORM + using CanPromote = std::function; + + void SetCanPromote(const CanPromote& canPromote); + + void RemoveCanPromote(); + + bool IsCanPromoteValid(); +#endif + #if ((defined DEBUG_REFBASE) && (!defined TRACK_ALL)) /** * @brief Enables tracking. It is applicable to debugging only. @@ -257,6 +267,9 @@ private: std::atomic atomicAttempt_; // Number of attempts RefPtrCallback callback_ = nullptr; // Callback function to deallocate the corresponding RefBase object static constexpr unsigned int FLAG_EXTEND_LIFE_TIME = 0x00000002; // Extended life-time bit to be set via logic-OR +#ifndef EMULATOR_PLATFORM + CanPromote canPromote_ = nullptr; +#endif #ifdef DEBUG_REFBASE #ifdef TRACK_ALL bool enableTrack = true; @@ -582,6 +595,10 @@ public: */ void EnableTracker(); +#ifndef EMULATOR_PLATFORM + virtual bool CanPromote(); +#endif + private: RefCounter *refs_ = nullptr; // Pointer to the corresponding reference // counter of this RefBase object diff --git a/base/src/refbase.cpp b/base/src/refbase.cpp index 999c5f1998d5357cf9f5e859a9ce17d4c0bd5459..cb7426f1ceb7e278c83f066afd98041341d9e7f2 100644 --- a/base/src/refbase.cpp +++ b/base/src/refbase.cpp @@ -211,6 +211,23 @@ bool RefCounter::IsRefPtrValid() return callback_ != nullptr; } +#ifndef EMULATOR_PLATFORM +void RefCounter::SetCanPromote(const CanPromote &canPromote) +{ + canPromote_ = canPromote; +} + +void RefCounter::RemoveCanPromote() +{ + canPromote_ = nullptr; +} + +bool RefCounter::IsCanPromoteValid() +{ + return canPromote_ != nullptr; +} +#endif + RefCounter::~RefCounter() { #ifdef DEBUG_REFBASE @@ -357,6 +374,11 @@ bool RefCounter::AttemptIncStrongRef(const void *objectId, int &outCount) } if (IsLifeTimeExtended()) { +#ifndef EMULATOR_PLATFORM + if (!IsCanPromoteValid() || !canPromote_()) { + return false; + } +#endif curCount = atomicStrong_.fetch_add(1, std::memory_order_relaxed); } @@ -396,6 +418,9 @@ RefBase::RefBase() : refs_(new RefCounter()) { refs_->IncRefCount(); refs_->SetCallback([this] { this->RefPtrCallback(); }); +#ifndef EMULATOR_PLATFORM + refs_->SetCanPromote([this] { return this->CanPromote(); }); +#endif } RefBase::RefBase(const RefBase &) @@ -404,9 +429,19 @@ RefBase::RefBase(const RefBase &) if (refs_ != nullptr) { refs_->IncRefCount(); refs_->SetCallback([this] { this->RefPtrCallback(); }); +#ifndef EMULATOR_PLATFORM + refs_->SetCanPromote([this] { return this->CanPromote(); }); +#endif } } +#ifndef EMULATOR_PLATFORM +bool RefBase::CanPromote() +{ + return true; +} +#endif + void RefBase::RefPtrCallback() { delete this; @@ -429,6 +464,9 @@ RefBase &RefBase::operator=(const RefBase &) if (refs_ != nullptr) { refs_->IncRefCount(); refs_->SetCallback([this] { this->RefPtrCallback(); }); +#ifndef EMULATOR_PLATFORM + refs_->SetCanPromote([this] { return this->CanPromote(); }); +#endif } return *this;