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: Jintao Zhu <zhu.jintao@gm.com> Change-Id: Ic2a183b5cc7c05f9ade95a0602d425badd3d97b1
This commit is contained in:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user