From a4e3731e4adb2ddeb7f07099ee99ebafd7b6b3b9 Mon Sep 17 00:00:00 2001 From: "bzbarsky%mit.edu" Date: Wed, 1 Jun 2005 15:43:08 +0000 Subject: [PATCH] Fix memory leak if a viewmanager has a child viewmanager. Bug 295656, r+sr=roc, a=shaver git-svn-id: svn://10.0.0.236/trunk@173924 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/view/src/nsViewManager.cpp | 20 ++++++++++---------- mozilla/view/src/nsViewManager.h | 3 ++- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/mozilla/view/src/nsViewManager.cpp b/mozilla/view/src/nsViewManager.cpp index a6a41e05e2e..b20892007b6 100644 --- a/mozilla/view/src/nsViewManager.cpp +++ b/mozilla/view/src/nsViewManager.cpp @@ -453,6 +453,7 @@ PRUint32 nsViewManager::gLastUserEventTime = 0; nsViewManager::nsViewManager() : mMouseLocation(NSCOORD_NONE, NSCOORD_NONE) , mDelayedResize(NSCOORD_NONE, NSCOORD_NONE) + , mRootViewManager(this) { if (gViewManagers == nsnull) { NS_ASSERTION(mVMCount == 0, "View Manager count is incorrect"); @@ -497,7 +498,7 @@ nsViewManager::~nsViewManager() if (!IsRootVM()) { // We have a strong ref to mRootViewManager - NS_IF_RELEASE(mRootViewManager); + NS_RELEASE(mRootViewManager); } mInvalidateEventQueue = nsnull; @@ -640,22 +641,21 @@ NS_IMETHODIMP nsViewManager::SetRootView(nsIView *aView) { nsView* view = NS_STATIC_CAST(nsView*, aView); + NS_PRECONDITION(!view || view->GetViewManager() == this, + "Unexpected viewmanager on root view"); + // Do NOT destroy the current root view. It's the caller's responsibility // to destroy it mRootView = view; if (mRootView) { - if (mRootViewManager && mRootViewManager != this) { - NS_RELEASE(mRootViewManager); - } nsView* parent = mRootView->GetParent(); if (parent) { + // Calling InsertChild on |parent| will InvalidateHierarchy() on us, so + // no need to set mRootViewManager ourselves here. parent->InsertChild(mRootView, nsnull); - mRootViewManager = parent->GetViewManager()->RootViewManager(); - NS_ASSERTION(mRootViewManager != this, "Something's wrong"); - NS_ADDREF(mRootViewManager); } else { - mRootViewManager = this; + InvalidateHierarchy(); } mRootView->SetZIndex(PR_FALSE, 0, PR_FALSE); @@ -4447,8 +4447,8 @@ void nsViewManager::InvalidateHierarchy() { if (mRootView) { - if (mRootViewManager != this) { - NS_IF_RELEASE(mRootViewManager); + if (!IsRootVM()) { + NS_RELEASE(mRootViewManager); } nsView *parent = mRootView->GetParent(); if (parent) { diff --git a/mozilla/view/src/nsViewManager.h b/mozilla/view/src/nsViewManager.h index d4df215c75b..82dde8f0f42 100644 --- a/mozilla/view/src/nsViewManager.h +++ b/mozilla/view/src/nsViewManager.h @@ -508,7 +508,8 @@ private: nsISupportsArray *mCompositeListeners; nsCOMPtr mRegionFactory; nsView *mRootView; - // mRootViewManager is a strong ref unless it equals |this| + // mRootViewManager is a strong ref unless it equals |this|. It's + // never null (if we have no ancestors, it will be |this|). nsViewManager *mRootViewManager; nsCOMPtr mEventQueueService; nsCOMPtr mSynthMouseMoveEventQueue;