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

Commit 1b9cf904 authored by Jintao Zhu's avatar Jintao Zhu Committed by Jintao Zhu
Browse files

NativeMessageQueue: ensure nativeDestroy success



android_os_MessageQueue_nativeDestroy leaves a cyclic reference between its Looper instance and its NativeMessageQueue instance, resulting in a memory and fd leak.

Solution: break the cyclic reference with weak pointer wp<>.

Bug: 244478726

Signed-off-by: default avatarJintao Zhu <zhu.jintao@gm.com>
Change-Id: Ic2a183b5cc7c05f9ade95a0602d425badd3d97b1
parent 7f5baabe
Loading
Loading
Loading
Loading
+35 −1
Original line number Diff line number Diff line
@@ -51,6 +51,21 @@ public:

    virtual int handleEvent(int fd, int events, void* data);

    /**
     * A simple proxy that holds a weak reference to a looper callback.
     */
    class WeakLooperCallback : public LooperCallback {
    protected:
        virtual ~WeakLooperCallback();

    public:
        WeakLooperCallback(const wp<LooperCallback>& callback);
        virtual int handleEvent(int fd, int events, void* data);

    private:
        wp<LooperCallback> mCallback;
    };

private:
    JNIEnv* mPollEnv;
    jobject mPollObj;
@@ -131,7 +146,8 @@ void NativeMessageQueue::setFileDescriptorEvents(int fd, int events) {
        if (events & CALLBACK_EVENT_OUTPUT) {
            looperEvents |= Looper::EVENT_OUTPUT;
        }
        mLooper->addFd(fd, Looper::POLL_CALLBACK, looperEvents, this,
        mLooper->addFd(fd, Looper::POLL_CALLBACK, looperEvents,
                sp<WeakLooperCallback>::make(this),
                reinterpret_cast<void*>(events));
    } else {
        mLooper->removeFd(fd);
@@ -162,6 +178,24 @@ int NativeMessageQueue::handleEvent(int fd, int looperEvents, void* data) {
}


// --- NativeMessageQueue::WeakLooperCallback ---

NativeMessageQueue::WeakLooperCallback::WeakLooperCallback(const wp<LooperCallback>& callback) :
        mCallback(callback) {
}

NativeMessageQueue::WeakLooperCallback::~WeakLooperCallback() {
}

int NativeMessageQueue::WeakLooperCallback::handleEvent(int fd, int events, void* data) {
    sp<LooperCallback> callback = mCallback.promote();
    if (callback != nullptr) {
        return callback->handleEvent(fd, events, data);
    }
    return 0;
}


// ----------------------------------------------------------------------------

sp<MessageQueue> android_os_MessageQueue_getMessageQueue(JNIEnv* env, jobject messageQueueObj) {