Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8e45b229 authored by Gabriel Biren's avatar Gabriel Biren Committed by Automerger Merge Worker
Browse files

Merge "Add a lock around any public methods in the AidlCallbackHandler." into...

Merge "Add a lock around any public methods in the AidlCallbackHandler." into udc-dev am: 51d06822

Original change: https://googleplex-android-review.googlesource.com/c/platform/hardware/interfaces/+/22723736



Change-Id: Ic03e37ae1fc462b8b46960610c7395809c4663a7
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents b0b84a6d 51d06822
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -19,11 +19,13 @@

#include <android-base/logging.h>

#include <mutex>
#include <set>
#include <unordered_map>

namespace {
std::unordered_map<void* /* callback */, void* /* handler */> callback_handler_map_;
std::mutex callback_handler_lock_;
}

namespace aidl {
@@ -43,6 +45,7 @@ class AidlCallbackHandler {
    ~AidlCallbackHandler() { invalidate(); }

    bool addCallback(const std::shared_ptr<CallbackType>& cb) {
        std::unique_lock<std::mutex> lk(callback_handler_lock_);
        void* cbPtr = reinterpret_cast<void*>(cb->asBinder().get());
        const auto& cbPosition = findCbInSet(cbPtr);
        if (cbPosition != cb_set_.end()) {
@@ -58,12 +61,18 @@ class AidlCallbackHandler {

        callback_handler_map_[cbPtr] = reinterpret_cast<void*>(this);
        cb_set_.insert(cb);
        // unique_lock unlocked here
        return true;
    }

    const std::set<std::shared_ptr<CallbackType>>& getCallbacks() { return cb_set_; }
    const std::set<std::shared_ptr<CallbackType>>& getCallbacks() {
        std::unique_lock<std::mutex> lk(callback_handler_lock_);
        // unique_lock unlocked here
        return cb_set_;
    }

    void invalidate() {
        std::unique_lock<std::mutex> lk(callback_handler_lock_);
        for (auto cb : cb_set_) {
            void* cookie = reinterpret_cast<void*>(cb->asBinder().get());
            if (AIBinder_unlinkToDeath(cb->asBinder().get(), death_handler_, cookie) != STATUS_OK) {
@@ -74,12 +83,14 @@ class AidlCallbackHandler {
            }
        }
        cb_set_.clear();
        // unique_lock unlocked here
    }

    // Entry point for the death handling logic. AIBinder_DeathRecipient
    // can only call a static function, so use the cookie to find the
    // proper handler and route the request there.
    static void onCallbackDeath(void* cookie) {
        std::unique_lock<std::mutex> lk(callback_handler_lock_);
        auto cbQuery = callback_handler_map_.find(cookie);
        if (cbQuery == callback_handler_map_.end()) {
            LOG(ERROR) << "Invalid death cookie received";
@@ -92,6 +103,7 @@ class AidlCallbackHandler {
            return;
        }
        cbHandler->handleCallbackDeath(cbQuery->first);
        // unique_lock unlocked here
    }

  private: