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

Commit 63a2d51e authored by Steven Moreland's avatar Steven Moreland
Browse files

libbinder: attachObject APIs work with threads

These APIs now return values so that they can be used in a
multi-threaded environment without needing additional locking.

Bug: 192023359
Test: binderLibTest
Change-Id: Idc9054bde869a57c2cb5142963aae362674ce0c0
parent 28318606
Loading
Loading
Loading
Loading
+7 −10
Original line number Diff line number Diff line
@@ -311,15 +311,13 @@ status_t BBinder::dump(int /*fd*/, const Vector<String16>& /*args*/)
    return NO_ERROR;
}

void BBinder::attachObject(
    const void* objectID, void* object, void* cleanupCookie,
    object_cleanup_func func)
{
void* BBinder::attachObject(const void* objectID, void* object, void* cleanupCookie,
                            object_cleanup_func func) {
    Extras* e = getOrCreateExtras();
    if (!e) return; // out of memory
    if (!e) return nullptr; // out of memory

    AutoMutex _l(e->mLock);
    e->mObjects.attach(objectID, object, cleanupCookie, func);
    return e->mObjects.attach(objectID, object, cleanupCookie, func);
}

void* BBinder::findObject(const void* objectID) const
@@ -331,13 +329,12 @@ void* BBinder::findObject(const void* objectID) const
    return e->mObjects.find(objectID);
}

void BBinder::detachObject(const void* objectID)
{
void* BBinder::detachObject(const void* objectID) {
    Extras* e = mExtras.load(std::memory_order_acquire);
    if (!e) return;
    if (!e) return nullptr;

    AutoMutex _l(e->mLock);
    e->mObjects.detach(objectID);
    return e->mObjects.detach(objectID);
}

BBinder* BBinder::localBinder()
+19 −20
Original line number Diff line number Diff line
@@ -61,22 +61,22 @@ BpBinder::ObjectManager::~ObjectManager()
    kill();
}

void BpBinder::ObjectManager::attach(
    const void* objectID, void* object, void* cleanupCookie,
    IBinder::object_cleanup_func func)
{
void* BpBinder::ObjectManager::attach(const void* objectID, void* object, void* cleanupCookie,
                                      IBinder::object_cleanup_func func) {
    entry_t e;
    e.object = object;
    e.cleanupCookie = cleanupCookie;
    e.func = func;

    if (mObjects.indexOfKey(objectID) >= 0) {
        ALOGE("Trying to attach object ID %p to binder ObjectManager %p with object %p, but object ID already in use",
    if (ssize_t idx = mObjects.indexOfKey(objectID); idx >= 0) {
        ALOGI("Trying to attach object ID %p to binder ObjectManager %p with object %p, but object "
              "ID already in use",
              objectID, this, object);
        return;
        return mObjects[idx].object;
    }

    mObjects.add(objectID, e);
    return nullptr;
}

void* BpBinder::ObjectManager::find(const void* objectID) const
@@ -86,9 +86,12 @@ void* BpBinder::ObjectManager::find(const void* objectID) const
    return mObjects.valueAt(i).object;
}

void BpBinder::ObjectManager::detach(const void* objectID)
{
    mObjects.removeItem(objectID);
void* BpBinder::ObjectManager::detach(const void* objectID) {
    ssize_t idx = mObjects.indexOfKey(objectID);
    if (idx < 0) return nullptr;
    void* value = mObjects[idx].object;
    mObjects.removeItemsAt(idx, 1);
    return value;
}

void BpBinder::ObjectManager::kill()
@@ -406,14 +409,11 @@ void BpBinder::reportOneDeath(const Obituary& obit)
    recipient->binderDied(wp<BpBinder>::fromExisting(this));
}


void BpBinder::attachObject(
    const void* objectID, void* object, void* cleanupCookie,
    object_cleanup_func func)
{
void* BpBinder::attachObject(const void* objectID, void* object, void* cleanupCookie,
                             object_cleanup_func func) {
    AutoMutex _l(mLock);
    ALOGV("Attaching object %p to binder %p (manager=%p)", object, this, &mObjects);
    mObjects.attach(objectID, object, cleanupCookie, func);
    return mObjects.attach(objectID, object, cleanupCookie, func);
}

void* BpBinder::findObject(const void* objectID) const
@@ -422,10 +422,9 @@ void* BpBinder::findObject(const void* objectID) const
    return mObjects.find(objectID);
}

void BpBinder::detachObject(const void* objectID)
{
void* BpBinder::detachObject(const void* objectID) {
    AutoMutex _l(mLock);
    mObjects.detach(objectID);
    return mObjects.detach(objectID);
}

BpBinder* BpBinder::remoteBinder()
+3 −5
Original line number Diff line number Diff line
@@ -54,12 +54,10 @@ public:
                                        uint32_t flags = 0,
                                        wp<DeathRecipient>* outRecipient = nullptr);

    virtual void        attachObject(   const void* objectID,
                                        void* object,
                                        void* cleanupCookie,
    virtual void* attachObject(const void* objectID, void* object, void* cleanupCookie,
                               object_cleanup_func func) final;
    virtual void*       findObject(const void* objectID) const final;
    virtual void        detachObject(const void* objectID) final;
    virtual void* detachObject(const void* objectID) final;

    virtual BBinder*    localBinder();

+13 −19
Original line number Diff line number Diff line
@@ -72,12 +72,10 @@ public:
                                        uint32_t flags = 0,
                                        wp<DeathRecipient>* outRecipient = nullptr);

    virtual void        attachObject(   const void* objectID,
                                        void* object,
                                        void* cleanupCookie,
    virtual void* attachObject(const void* objectID, void* object, void* cleanupCookie,
                               object_cleanup_func func) final;
    virtual void*       findObject(const void* objectID) const final;
    virtual void        detachObject(const void* objectID) final;
    virtual void* detachObject(const void* objectID) final;

    virtual BpBinder*   remoteBinder();

@@ -91,18 +89,15 @@ public:
    static void         setLimitCallback(binder_proxy_limit_callback cb);
    static void         setBinderProxyCountWatermarks(int high, int low);

    class ObjectManager
    {
    class ObjectManager {
    public:
        ObjectManager();
        ~ObjectManager();

        void        attach( const void* objectID,
                            void* object,
                            void* cleanupCookie,
        void* attach(const void* objectID, void* object, void* cleanupCookie,
                     IBinder::object_cleanup_func func);
        void* find(const void* objectID) const;
        void        detach(const void* objectID);
        void* detach(const void* objectID);

        void kill();

@@ -110,8 +105,7 @@ public:
        ObjectManager(const ObjectManager&);
        ObjectManager& operator=(const ObjectManager&);

        struct entry_t
        {
        struct entry_t {
            void* object;
            void* cleanupCookie;
            IBinder::object_cleanup_func func;
+10 −13
Original line number Diff line number Diff line
@@ -255,26 +255,23 @@ public:
     * objects are invoked with their respective objectID, object, and
     * cleanupCookie. Access to these APIs can be made from multiple threads,
     * but calls from different threads are allowed to be interleaved.
     *
     * This returns the object which is already attached. If this returns a
     * non-null value, it means that attachObject failed. TODO(b/192023359):
     * remove logs and add [[nodiscard]]
     */
    virtual void            attachObject(   const void* objectID,
                                            void* object,
                                            void* cleanupCookie,
    virtual void* attachObject(const void* objectID, void* object, void* cleanupCookie,
                               object_cleanup_func func) = 0;
    /**
     * Returns object attached with attachObject.
     */
    virtual void*           findObject(const void* objectID) const = 0;
    /**
     * WARNING: this API does not call the cleanup function for legacy reasons.
     * It also does not return void* for legacy reasons. If you need to detach
     * an object and destroy it, there are two options:
     * - if you can, don't call detachObject and instead wait for the destructor
     *   to clean it up.
     * - manually retrieve and destruct the object (if multiple of your threads
     *   are accessing these APIs, you must guarantee that attachObject isn't
     *   called after findObject and before detachObject is called).
     * Returns object attached with attachObject, and detaches it. This does not
     * delete the object. This is equivalent to using attachObject to attach a null
     * object.
     */
    virtual void            detachObject(const void* objectID) = 0;
    virtual void* detachObject(const void* objectID) = 0;

    virtual BBinder*        localBinder();
    virtual BpBinder*       remoteBinder();
Loading