mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 04:15:43 +00:00
Fix for bug 16818. xpcom proxy does not handle classes with two or more
interfaces correctly. What happens is the real object is addref incorrectly and will never be deleted. r=jud
This commit is contained in:
parent
cd3aff8be9
commit
fd24e9df56
@ -36,6 +36,8 @@ class nsProxyObjectCallInfo;
|
||||
#define PROXY_ASYNC 0x0002 // fire and forget. This will return immediately and you will lose all return information.
|
||||
#define PROXY_ALWAYS 0x0004 // ignore check to see if the eventQ is on the same thread as the caller, and alway return a proxied object.
|
||||
|
||||
//#define AUTOPROXIFICATION
|
||||
|
||||
// WARNING about PROXY_ASYNC:
|
||||
//
|
||||
// If the calling thread goes away, any function which accesses the calling stack
|
||||
|
@ -87,9 +87,6 @@ nsProxyObject::nsProxyObject(nsIEventQueue *destQueue, PRInt32 proxyType, nsISup
|
||||
mRealObject = realObject;
|
||||
mProxyType = proxyType;
|
||||
mDestQueue = destQueue;
|
||||
|
||||
NS_ADDREF(mRealObject);
|
||||
NS_ADDREF(mDestQueue);
|
||||
}
|
||||
|
||||
|
||||
@ -98,7 +95,6 @@ nsProxyObject::nsProxyObject(nsIEventQueue *destQueue, PRInt32 proxyType, const
|
||||
NS_INIT_REFCNT();
|
||||
NS_ADDREF_THIS();
|
||||
|
||||
|
||||
nsComponentManager::CreateInstance(aClass,
|
||||
aDelegate,
|
||||
aIID,
|
||||
@ -106,8 +102,6 @@ nsProxyObject::nsProxyObject(nsIEventQueue *destQueue, PRInt32 proxyType, const
|
||||
|
||||
mProxyType = proxyType;
|
||||
mDestQueue = destQueue;
|
||||
|
||||
NS_ADDREF(mDestQueue);
|
||||
}
|
||||
|
||||
nsProxyObject::~nsProxyObject()
|
||||
@ -402,7 +396,7 @@ nsProxyObject::AutoProxyParameterList(PRUint32 methodIndex, nsXPTMethodInfo *met
|
||||
{
|
||||
NS_WITH_SERVICE(nsIEventQueueService, eventQService, kEventQueueServiceCID, &rv);
|
||||
if ( NS_FAILED( rv ) )
|
||||
return rv
|
||||
return rv;
|
||||
|
||||
rv = eventQService->GetThreadEventQueue(PR_CurrentThread(), &eventQ);
|
||||
if ( NS_FAILED( rv ) )
|
||||
|
@ -90,6 +90,9 @@ nsProxyEventObject::GetNewOrUsedProxy(nsIEventQueue *destQueue,
|
||||
{
|
||||
nsVoidKey aKey(root);
|
||||
realToProxyMap->Put(&aKey, root);
|
||||
|
||||
NS_ADDREF(proxy); // since we are double duty, we need to make sure that our refCnt
|
||||
// reflects this.
|
||||
}
|
||||
goto return_wrapper;
|
||||
}
|
||||
@ -223,22 +226,16 @@ nsrefcnt
|
||||
nsProxyEventObject::Release(void)
|
||||
{
|
||||
NS_PRECONDITION(mRoot, "bad root");
|
||||
NS_PRECONDITION(0 != mRefCnt, "dup release");
|
||||
|
||||
--mRefCnt;
|
||||
NS_LOG_RELEASE(this, mRefCnt, "nsProxyEventObject");
|
||||
if (mRefCnt == 0)
|
||||
|
||||
if(0 == mRefCnt)
|
||||
{
|
||||
if(mRoot == this)
|
||||
{
|
||||
NS_DELETEXPCOM(this); // cascaded delete
|
||||
}
|
||||
else
|
||||
{
|
||||
mRoot->Release();
|
||||
}
|
||||
NS_DELETEXPCOM(this);
|
||||
return 0;
|
||||
}
|
||||
else if(1 == mRefCnt)
|
||||
mRoot->Release(); // do NOT zero out the ptr (weak ref)
|
||||
return mRefCnt;
|
||||
}
|
||||
|
||||
|
@ -179,6 +179,8 @@ nsProxyObjectManager::GetProxyObject(nsIEventQueue *destQueue, REFNSIID aIID, ns
|
||||
return aObj->QueryInterface(aIID, aProxyObject);
|
||||
}
|
||||
}
|
||||
|
||||
NS_ADDREF(aObj);
|
||||
|
||||
// check to see if proxy is there or not.
|
||||
*aProxyObject = nsProxyEventObject::GetNewOrUsedProxy(postQ, proxyType, aObj, aIID);
|
||||
@ -187,6 +189,8 @@ nsProxyObjectManager::GetProxyObject(nsIEventQueue *destQueue, REFNSIID aIID, ns
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_RELEASE(aObj);
|
||||
|
||||
return NS_ERROR_NO_INTERFACE; //fix error code?
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user