From fa00efddbb22cda2dabf6e0629de27ad40bbe45b Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Tue, 10 May 2016 16:02:11 +0200 Subject: [PATCH] fix memory leak in JNI getHistory() --- coreapi/linphonecore_jni.cc | 6 ++++-- coreapi/message_storage.c | 5 ++--- java/common/org/linphone/core/LinphoneChatMessage.java | 7 +++++++ .../org/linphone/core/LinphoneChatMessageImpl.java | 10 ++++++++-- 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 9083fbfc1..1b4a4e09f 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -3727,10 +3727,12 @@ extern "C" jobjectArray _LinphoneChatRoomImpl_getHistory(JNIEnv* env, jobject th env->SetObjectArrayElement(jHistory, i, jmsg); env->DeleteLocalRef(jmsg); } + history = history->next; } - - ms_list_free(list); + /*getChatMessage() acquired a ref that is "transfered" to the java object. We must drop + * the reference given by linphone_chat_room_get_history_range()*/ + ms_list_free_with_data(list, (void (*)(void*))linphone_chat_message_unref); return jHistory; } extern "C" jobjectArray Java_org_linphone_core_LinphoneChatRoomImpl_getHistoryRange(JNIEnv* env diff --git a/coreapi/message_storage.c b/coreapi/message_storage.c index 37a690a83..4d81ef768 100644 --- a/coreapi/message_storage.c +++ b/coreapi/message_storage.c @@ -193,13 +193,12 @@ static int create_chat_message(void *data, int argc, char **argv, char **colName if(atoi(argv[3])==LinphoneChatMessageIncoming){ new_message->dir=LinphoneChatMessageIncoming; linphone_chat_message_set_from(new_message,linphone_chat_room_get_peer_address(cr)); - linphone_chat_message_set_to(new_message,local_addr); + new_message->to = local_addr; /*direct assignation to avoid a copy*/ } else { new_message->dir=LinphoneChatMessageOutgoing; - linphone_chat_message_set_from(new_message,local_addr); + new_message->from = local_addr; /*direct assignation to avoid a copy*/ linphone_chat_message_set_to(new_message,linphone_chat_room_get_peer_address(cr)); } - linphone_address_destroy(local_addr); new_message->time = (time_t)atol(argv[9]); new_message->is_read=atoi(argv[6]); diff --git a/java/common/org/linphone/core/LinphoneChatMessage.java b/java/common/org/linphone/core/LinphoneChatMessage.java index aaef154ab..fab2bab28 100644 --- a/java/common/org/linphone/core/LinphoneChatMessage.java +++ b/java/common/org/linphone/core/LinphoneChatMessage.java @@ -234,5 +234,12 @@ public interface LinphoneChatMessage { * @throw LinphoneCoreExeption . */ void putChar(long character) throws LinphoneCoreException; + + /** + * Frees the underlying native resource of the message. + * It should not be accessed afterwards. + * This is for optimizing the memory resources at runtime. Not calling this does not result in a memory leak. + **/ + void destroy(); } diff --git a/java/impl/org/linphone/core/LinphoneChatMessageImpl.java b/java/impl/org/linphone/core/LinphoneChatMessageImpl.java index d71ffc6a5..d36446737 100644 --- a/java/impl/org/linphone/core/LinphoneChatMessageImpl.java +++ b/java/impl/org/linphone/core/LinphoneChatMessageImpl.java @@ -3,7 +3,7 @@ package org.linphone.core; import java.io.UnsupportedEncodingException; public class LinphoneChatMessageImpl implements LinphoneChatMessage { - protected final long nativePtr; + protected long nativePtr; private native byte[] getText(long ptr); private native long getPeerAddress(long ptr); private native String getExternalBodyUrl(long ptr); @@ -112,7 +112,7 @@ public class LinphoneChatMessageImpl implements LinphoneChatMessage { return new ErrorInfoImpl(getErrorInfo(nativePtr)); } protected void finalize() throws Throwable{ - unref(nativePtr); + destroy(); super.finalize(); } @@ -160,4 +160,10 @@ public class LinphoneChatMessageImpl implements LinphoneChatMessage { public void putChar(long character) throws LinphoneCoreException { putChar(nativePtr, character); } + public void destroy(){ + if (nativePtr != 0) { + unref(nativePtr); + nativePtr = 0; + } + } }