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

Commit fd4d0b9c authored by Praveen Chavan's avatar Praveen Chavan Committed by Wonsik Kim
Browse files

Codec2: Detect and release component if the client process terminates

Attach death-notifier to listen to the client process termination
from the HAL process (specifically, register death-recipient with
the remote ComponentListener object).
Invoke release() on component to clean-up the resources gracefully
on client's death.
This avoids race conditions that may result from the listener's
context holding the last-strong-reference and trying to destruct
the component from within one of it's own calling contexts.
( Eg: Component destructor invoked from onWorkDone(..) )

Test:
   simulate delay in /hidl/1.1/utils/Component.cpp::onWorkDone_nb()
   play a video and 'adb shell killall com.google.android.apps.photos'
   Component is released and destroyed

b/175311561

CRs-Fixed: 2787177

Change-Id: I4411a5d6dd82b6e4e12f142610f6fad13aa11994
parent 809b7549
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
@@ -482,6 +482,37 @@ void Component::initListener(const sp<Component>& self) {
    if (res != C2_OK) {
        mInit = res;
    }

    struct ListenerDeathRecipient : public HwDeathRecipient {
        ListenerDeathRecipient(const wp<Component>& comp)
            : mComponent{comp} {
        }

        virtual void serviceDied(
                uint64_t /* cookie */,
                const wp<::android::hidl::base::V1_0::IBase>& /* who */
                ) override {
            auto strongComponent = mComponent.promote();
            if (strongComponent) {
                LOG(INFO) << "Client died ! release the component !!";
                strongComponent->release();
            } else {
                LOG(ERROR) << "Client died ! no component to release !!";
            }
        }

        wp<Component> mComponent;
    };

    mDeathRecipient = new ListenerDeathRecipient(self);
    Return<bool> transStatus = mListener->linkToDeath(
            mDeathRecipient, 0);
    if (!transStatus.isOk()) {
        LOG(ERROR) << "Listener linkToDeath() transaction failed.";
    }
    if (!static_cast<bool>(transStatus)) {
        LOG(DEBUG) << "Listener linkToDeath() call failed.";
    }
}

Component::~Component() {
+3 −0
Original line number Diff line number Diff line
@@ -132,6 +132,9 @@ protected:
    friend struct ComponentStore;

    struct Listener;

    using HwDeathRecipient = ::android::hardware::hidl_death_recipient;
    sp<HwDeathRecipient> mDeathRecipient;
};

}  // namespace utils
+31 −0
Original line number Diff line number Diff line
@@ -489,6 +489,37 @@ void Component::initListener(const sp<Component>& self) {
    if (res != C2_OK) {
        mInit = res;
    }

    struct ListenerDeathRecipient : public HwDeathRecipient {
        ListenerDeathRecipient(const wp<Component>& comp)
            : component{comp} {
        }

        virtual void serviceDied(
                uint64_t /* cookie */,
                const wp<::android::hidl::base::V1_0::IBase>& /* who */
                ) override {
            auto strongComponent = component.promote();
            if (strongComponent) {
                LOG(INFO) << "Client died ! release the component !!";
                strongComponent->release();
            } else {
                LOG(ERROR) << "Client died ! no component to release !!";
            }
        }

        wp<Component> component;
    };

    mDeathRecipient = new ListenerDeathRecipient(self);
    Return<bool> transStatus = mListener->linkToDeath(
            mDeathRecipient, 0);
    if (!transStatus.isOk()) {
        LOG(ERROR) << "Listener linkToDeath() transaction failed.";
    }
    if (!static_cast<bool>(transStatus)) {
        LOG(DEBUG) << "Listener linkToDeath() call failed.";
    }
}

Component::~Component() {
+3 −0
Original line number Diff line number Diff line
@@ -137,6 +137,9 @@ protected:
    friend struct ComponentStore;

    struct Listener;

    using HwDeathRecipient = ::android::hardware::hidl_death_recipient;
    sp<HwDeathRecipient> mDeathRecipient;
};

} // namespace utils