Fix several memory leaks. Also, use monitors around sensetive structures.

Original committer: pedemont%us.ibm.com
Original revision: 1.23
Original date: 2005/02/24 23:17:36
This commit is contained in:
pedemont%us.ibm.com 2006-09-27 15:18:11 +00:00
Родитель 9099d9e10a
Коммит 7a5c700888
2 изменённых файлов: 60 добавлений и 36 удалений

Просмотреть файл

@ -374,27 +374,22 @@ SetupParams(JNIEnv *env, const jobject aParam, const nsXPTParamInfo &aParamInfo,
rv = NS_ERROR_OUT_OF_MEMORY;
break;
}
NS_RELEASE(xpcom_obj);
xpcom_obj = weakref;
NS_ADDREF(xpcom_obj);
aVariant.SetValIsAllocated();
} else { // if is native XPCOM object
nsCOMPtr<nsISupportsWeakReference> supportsweak =
do_QueryInterface(xpcom_obj);
if (supportsweak) {
nsWeakPtr weakref;
supportsweak->GetWeakReference(getter_AddRefs(weakref));
NS_RELEASE(xpcom_obj);
xpcom_obj = weakref;
NS_ADDREF(xpcom_obj);
} else {
xpcom_obj = nsnull;
}
}
} else if (isXPTCStub) {
aVariant.SetValIsAllocated();
} else { // if is native XPCOM object
xpcom_obj->Release();
}
} else {
xpcom_obj = nsnull;
@ -618,7 +613,6 @@ FinalizeParams(JNIEnv *env, const jobject aParam,
PRUint32 length = nsCRT::strlen((const PRUnichar*) aVariant.val.p);
str = env->NewString((const jchar*) aVariant.val.p, length);
}
nsMemory::Free(aVariant.val.p);
if (!str) {
rv = NS_ERROR_OUT_OF_MEMORY;
break;
@ -693,11 +687,7 @@ FinalizeParams(JNIEnv *env, const jobject aParam,
env->SetObjectArrayElement((jobjectArray) aParam, 0, java_obj);
}
// If VAL_IS_ALLOCD is set, that means that an XPCOM object was created
// is SetupParams that now needs to be released.
if (xpcom_obj && aVariant.IsValAllocated()) {
NS_RELEASE(xpcom_obj);
}
NS_IF_RELEASE(xpcom_obj);
}
break;
@ -770,6 +760,9 @@ FinalizeParams(JNIEnv *env, const jobject aParam,
return rv;
}
/**
* Handles 'retval' and 'dipper' params.
*/
nsresult
SetRetval(JNIEnv *env, const nsXPTParamInfo &aParamInfo,
const nsXPTMethodInfo* aMethodInfo, nsIInterfaceInfo* aIInfo,
@ -901,12 +894,13 @@ SetRetval(JNIEnv *env, const nsXPTParamInfo &aParamInfo,
case nsXPTType::T_DOMSTRING:
{
if (aVariant.ptr) {
nsString* str = (nsString*) aVariant.ptr;
nsString* str = NS_STATIC_CAST(nsString*, aVariant.ptr);
*result = env->NewString(str->get(), str->Length());
if (*result == nsnull) {
rv = NS_ERROR_OUT_OF_MEMORY;
break;
}
delete str;
}
}
break;
@ -915,12 +909,13 @@ SetRetval(JNIEnv *env, const nsXPTParamInfo &aParamInfo,
case nsXPTType::T_CSTRING:
{
if (aVariant.ptr) {
nsCString* str = (nsCString*) aVariant.ptr;
nsCString* str = NS_STATIC_CAST(nsCString*, aVariant.ptr);
*result = env->NewStringUTF(str->get());
if (*result == nsnull) {
rv = NS_ERROR_OUT_OF_MEMORY;
break;
}
delete str;
}
}
break;
@ -1094,7 +1089,7 @@ JAVAPROXY_NATIVE(callXPCOMMethod) (JNIEnv *env, jclass that, jobject aJavaProxy,
rv = SetupParams(env, env->GetObjectArrayElement(aParams, i), paramInfo,
methodInfo, iinfo, methodIndex, params, params[i]);
} else if (paramInfo.IsDipper()) {
LOG(("dipper"));
LOG(("dipper\n"));
const nsXPTType &type = paramInfo.GetType();
switch (type.TagPart())
{
@ -1173,7 +1168,7 @@ JAVAPROXY_NATIVE(callXPCOMMethod) (JNIEnv *env, jclass that, jobject aJavaProxy,
const nsXPTParamInfo &paramInfo = methodInfo->GetParam(j);
const nsXPTType &type = paramInfo.GetType();
if (type.TagPart() == nsXPTType::T_IID) {
nsID* iid = (nsID*) params[j].ptr;
nsID* iid = (nsID*) params[j].val.p;
delete iid;
}
}
@ -1243,8 +1238,8 @@ CreateJavaProxy(JNIEnv* env, nsISupports* aXPCOMObject, const nsIID& aIID,
#ifdef DEBUG_JAVAXPCOM
char* iid_str = aIID.ToString();
LOG(("+ CreateJavaProxy (Java=%08x | XPCOM=%08x | IID=%s)\n",
env->CallIntMethod(java_obj, hashCodeMID),
(int) aXPCOMObject, iid_str));
(PRUint32) env->CallIntMethod(java_obj, hashCodeMID),
(PRUint32) aXPCOMObject, iid_str));
PR_Free(iid_str);
#endif
@ -1285,8 +1280,8 @@ GetXPCOMInstFromProxy(JNIEnv* env, jobject aJavaObject, void** aResult)
inst->InterfaceInfo()->GetInterfaceIID(&iid);
char* iid_str = iid->ToString();
LOG(("< GetXPCOMInstFromProxy (Java=%08x | XPCOM=%08x | IID=%s)\n",
env->CallIntMethod(aJavaObject, hashCodeMID),
(int) inst->GetInstance(), iid_str));
(PRUint32) env->CallIntMethod(aJavaObject, hashCodeMID),
(PRUint32) inst->GetInstance(), iid_str));
PR_Free(iid_str);
nsMemory::Free(iid);
#endif
@ -1299,33 +1294,38 @@ GetXPCOMInstFromProxy(JNIEnv* env, jobject aJavaObject, void** aResult)
extern "C" JX_EXPORT void JNICALL
JAVAPROXY_NATIVE(finalizeProxy) (JNIEnv *env, jclass that, jobject aJavaProxy)
{
#ifdef DEBUG_JAVAXPCOM
PRUint32 xpcom_addr = 0;
#endif
// Due to Java's garbage collection, this finalize statement may get called
// after FreeJavaGlobals(). So check to make sure that everything is still
// initialized.
if (gJavaXPCOMLock) {
nsAutoLock lock(gJavaXPCOMLock);
if (gJavaXPCOMMonitor) {
nsAutoMonitor mon(gJavaXPCOMMonitor);
// Get native XPCOM instance
void* xpcom_obj;
nsresult rv = GetXPCOMInstFromProxy(env, aJavaProxy, &xpcom_obj);
if (NS_SUCCEEDED(rv)) {
JavaXPCOMInstance* inst = NS_STATIC_CAST(JavaXPCOMInstance*, xpcom_obj);
#ifdef DEBUG_JAVAXPCOM
xpcom_addr = NS_REINTERPRET_CAST(PRUint32, inst->GetInstance());
#endif
nsIID* iid;
rv = inst->InterfaceInfo()->GetInterfaceIID(&iid);
if (NS_SUCCEEDED(rv)) {
rv = gNativeToJavaProxyMap->Remove(env, inst->GetInstance(), *iid);
#ifdef DEBUG_JAVAXPCOM
char* iid_str = iid->ToString();
LOG(("- Finalize (Java=%08x | XPCOM=%08x | IID=%s)\n",
env->CallIntMethod(aJavaProxy, hashCodeMID),
(int) inst->GetInstance(), iid_str));
PR_Free(iid_str);
#endif
nsMemory::Free(iid);
}
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to RemoveJavaProxy");
delete inst;
}
}
#ifdef DEBUG_JAVAXPCOM
LOG(("- Finalize (Java=%08x | XPCOM=%08x)\n",
(PRUint32) env->CallIntMethod(aJavaProxy, hashCodeMID), xpcom_addr));
#endif
}

Просмотреть файл

@ -110,7 +110,10 @@ extern NativeToJavaProxyMap* gNativeToJavaProxyMap;
class JavaToXPTCStubMap;
extern JavaToXPTCStubMap* gJavaToXPTCStubMap;
extern PRLock* gJavaXPCOMLock;
// The Java garbage collector runs in a separate thread. Since it calls the
// finalizeProxy() function in nsJavaWrapper.cpp, we need to make sure that
// all the structures touched by finalizeProxy() are multithread aware.
extern PRMonitor* gJavaXPCOMMonitor;
/**
* Initialize global structures used by Javaconnect.
@ -154,6 +157,11 @@ private:
*/
class NativeToJavaProxyMap
{
friend PLDHashOperator DestroyJavaProxyMappingEnum(PLDHashTable* aTable,
PLDHashEntryHdr* aHeader,
PRUint32 aNumber,
void* aData);
protected:
struct ProxyList
{
@ -179,10 +187,16 @@ public:
: mHashTable(nsnull)
{ }
~NativeToJavaProxyMap();
~NativeToJavaProxyMap()
{
NS_ASSERTION(mHashTable == nsnull,
"MUST call Destroy() before deleting object");
}
nsresult Init();
nsresult Destroy(JNIEnv* env);
nsresult Add(JNIEnv* env, nsISupports* aXPCOMObject, const nsIID& aIID,
jobject aProxy);
@ -200,11 +214,15 @@ protected:
*/
class JavaToXPTCStubMap
{
friend PLDHashOperator DestroyXPTCMappingEnum(PLDHashTable* aTable,
PLDHashEntryHdr* aHeader,
PRUint32 aNumber, void* aData);
protected:
struct Entry : public PLDHashEntryHdr
{
jint key;
nsJavaXPTCStub* xptcstub;
jint key;
nsJavaXPTCStub* xptcstub;
};
public:
@ -212,10 +230,16 @@ public:
: mHashTable(nsnull)
{ }
~JavaToXPTCStubMap();
~JavaToXPTCStubMap()
{
NS_ASSERTION(mHashTable == nsnull,
"MUST call Destroy() before deleting object");
}
nsresult Init();
nsresult Destroy();
nsresult Add(JNIEnv* env, jobject aJavaObject, nsJavaXPTCStub* aProxy);
nsresult Find(JNIEnv* env, jobject aJavaObject, const nsIID& aIID,
@ -300,7 +324,7 @@ void ThrowException(JNIEnv* env, const nsresult aErrorCode,
/**
* Helper functions for converting from java.lang.String to
* nsAString/nsACstring.
* nsAString/nsACstring. Caller must delete nsAString/nsACString.
*
* @param env Java environment pointer
* @param aString Java string to convert