Fixes a cycle between docshelltreeowner and layout which caused a huge

leak. r=adamlock@netscape.com
This commit is contained in:
dougt%netscape.com 2000-09-01 19:38:46 +00:00
Родитель 05379784aa
Коммит c9d4bac2bd
2 изменённых файлов: 55 добавлений и 6 удалений

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

@ -57,7 +57,8 @@ nsDocShellTreeOwner::nsDocShellTreeOwner() :
mWebBrowserChrome(nsnull),
mOwnerProgressListener(nsnull),
mOwnerWin(nsnull),
mOwnerRequestor(nsnull)
mOwnerRequestor(nsnull),
mMouseListenerActive(PR_FALSE)
{
NS_INIT_REFCNT();
}
@ -71,7 +72,36 @@ nsDocShellTreeOwner::~nsDocShellTreeOwner()
//*****************************************************************************
NS_IMPL_ADDREF(nsDocShellTreeOwner)
NS_IMPL_RELEASE(nsDocShellTreeOwner)
//NS_IMPL_RELEASE(nsDocShellTreeOwner)
// Custom release to break a circular dependancy cause
// by an refcount held by layout.
NS_IMETHODIMP_(nsrefcnt)
nsDocShellTreeOwner::Release(void)
{
nsrefcnt count = PR_AtomicDecrement((PRInt32 *)&mRefCnt);
NS_LOG_RELEASE(this, count, "nsDocShellTreeOwner");
if (count == 1 && mMouseListenerActive)
{
// layout holds a reference via the MouseListener.
// we will remove ourselves, layout will call release
// on us.
RemoveMouseListener();
return 0;
}
if (count == 0)
{
NS_DELETEXPCOM(this);
return 0;
}
return mRefCnt;
}
NS_INTERFACE_MAP_BEGIN(nsDocShellTreeOwner)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDocShellTreeOwner)
@ -578,8 +608,11 @@ NS_IMETHODIMP nsDocShellTreeOwner::AddMouseListener()
domDocument->QueryInterface(NS_GET_IID(nsIDOMEventReceiver), getter_AddRefs(eventReceiver));
if (eventReceiver)
{
nsresult rv;
nsIDOMMouseListener *pListener = NS_STATIC_CAST(nsIDOMMouseListener *, this);
eventReceiver->AddEventListenerByIID(pListener, NS_GET_IID(nsIDOMMouseListener));
rv = eventReceiver->AddEventListenerByIID(pListener, NS_GET_IID(nsIDOMMouseListener));
if (NS_SUCCEEDED(rv))
mMouseListenerActive = PR_TRUE;
}
mLastDOMDocument = domDocument;
@ -596,9 +629,12 @@ NS_IMETHODIMP nsDocShellTreeOwner::RemoveMouseListener()
mLastDOMDocument->QueryInterface(NS_GET_IID(nsIDOMEventReceiver), getter_AddRefs(eventReceiver));
if (eventReceiver)
{
nsIDOMMouseListener *pListener = NS_STATIC_CAST(nsIDOMMouseListener *, this);
eventReceiver->RemoveEventListenerByIID(pListener, NS_GET_IID(nsIDOMMouseListener));
}
nsresult rv;
nsIDOMMouseListener *pListener = NS_STATIC_CAST(nsIDOMMouseListener *, this);
rv = eventReceiver->RemoveEventListenerByIID(pListener, NS_GET_IID(nsIDOMMouseListener));
if (NS_SUCCEEDED(rv))
mMouseListenerActive = PR_FALSE;
}
mLastDOMDocument = nsnull;
}

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

@ -108,6 +108,19 @@ protected:
nsIWebProgressListener* mOwnerProgressListener;
nsIBaseWindow* mOwnerWin;
nsIInterfaceRequestor* mOwnerRequestor;
PRBool mMouseListenerActive;
};
#endif /* nsDocShellTreeOwner_h__ */