From db23565e424ba3e5f9801ec4c3a5a0ee35042899 Mon Sep 17 00:00:00 2001 From: "sfraser%netscape.com" Date: Tue, 12 Feb 2002 01:22:23 +0000 Subject: [PATCH] Fix bug 124517 -- double delete caused by making more than one nsMacMemoryCushion object (one for each event loop). This should fix a ton of random crashes on Mac. r=pinkerton, sr=beard --- widget/src/mac/nsAppShell.cpp | 24 +++++++++--------------- widget/src/mac/nsAppShell.h | 3 --- widget/src/mac/nsToolkit.cpp | 29 +++++++++++++++++++++++++++++ widget/src/mac/nsToolkit.h | 7 +++++-- 4 files changed, 43 insertions(+), 20 deletions(-) diff --git a/widget/src/mac/nsAppShell.cpp b/widget/src/mac/nsAppShell.cpp index 4ba9b11c4b69..b6c3618775fe 100644 --- a/widget/src/mac/nsAppShell.cpp +++ b/widget/src/mac/nsAppShell.cpp @@ -93,22 +93,17 @@ NS_IMETHODIMP nsAppShell::SetDispatchListener(nsDispatchListener* aDispatchListe NS_IMETHODIMP nsAppShell::Create(int* argc, char ** argv) { - nsresult rv; - rv = NS_GetCurrentToolkit(getter_AddRefs(mToolkit)); - if (NS_FAILED(rv)) - return rv; - nsIToolkit* toolkit = mToolkit.get(); - mMacPump.reset(new nsMacMessagePump(static_cast(toolkit))); - mMacMemoryCushion.reset(new nsMacMemoryCushion()); + nsresult rv = NS_GetCurrentToolkit(getter_AddRefs(mToolkit)); + if (NS_FAILED(rv)) + return rv; - if (!mMacPump.get() || !mMacMemoryCushion.get()) + nsIToolkit* toolkit = mToolkit.get(); + mMacPump.reset(new nsMacMessagePump(static_cast(toolkit))); + + if (!mMacPump.get() || ! nsMacMemoryCushion::EnsureMemoryCushion()) return NS_ERROR_OUT_OF_MEMORY; - - OSErr err = mMacMemoryCushion->Init(nsMacMemoryCushion::kMemoryBufferSize, nsMacMemoryCushion::kMemoryReserveSize); - if (err != noErr) - return NS_ERROR_FAILURE; - - return NS_OK; + + return NS_OK; } //------------------------------------------------------------------------- @@ -121,7 +116,6 @@ NS_IMETHODIMP nsAppShell::Run(void) if (!mMacPump.get()) return NS_ERROR_NOT_INITIALIZED; - mMacMemoryCushion->StartRepeating(); mMacPump->StartRunning(); mMacPump->DoMessagePump(); diff --git a/widget/src/mac/nsAppShell.h b/widget/src/mac/nsAppShell.h index b806fc7eb75f..e89c819ea37c 100644 --- a/widget/src/mac/nsAppShell.h +++ b/widget/src/mac/nsAppShell.h @@ -56,8 +56,6 @@ using std::auto_ptr; class nsMacMessagePump; -class nsMacMemoryCushion; - class nsAppShell : public nsIAppShell { @@ -72,7 +70,6 @@ class nsAppShell : public nsIAppShell nsDispatchListener *mDispatchListener; // note: we don't own this, but it can be NULL nsCOMPtr mToolkit; auto_ptr mMacPump; - auto_ptr mMacMemoryCushion; PRBool mExitCalled; static PRBool mInitializedToolbox; }; diff --git a/widget/src/mac/nsToolkit.cpp b/widget/src/mac/nsToolkit.cpp index 717bfa01ca66..ccaa83f1e9aa 100644 --- a/widget/src/mac/nsToolkit.cpp +++ b/widget/src/mac/nsToolkit.cpp @@ -384,9 +384,15 @@ nsMacMemoryCushion::nsMacMemoryCushion() nsMacMemoryCushion::~nsMacMemoryCushion() { + StopRepeating(); ::SetGrowZone(nsnull); + + NS_ASSERTION(sMemoryReserve, "Memory reserve was nil"); if (sMemoryReserve) + { ::DisposeHandle(sMemoryReserve); + sMemoryReserve = nil; + } if (mBufferHandle) ::DisposeHandle(mBufferHandle); @@ -460,3 +466,26 @@ pascal long nsMacMemoryCushion::GrowZoneProc(Size amountNeeded) return freedMem; } +std::auto_ptr gMemoryCushion; + +Boolean nsMacMemoryCushion::EnsureMemoryCushion() +{ + if (!gMemoryCushion.get()) + { + nsMacMemoryCushion* softFluffyCushion = new nsMacMemoryCushion(); + if (!softFluffyCushion) return false; + + OSErr err = softFluffyCushion->Init(nsMacMemoryCushion::kMemoryBufferSize, nsMacMemoryCushion::kMemoryReserveSize); + if (err != noErr) + { + delete softFluffyCushion; + return false; + } + + gMemoryCushion.reset(softFluffyCushion); + softFluffyCushion->StartRepeating(); + } + + return true; +} + diff --git a/widget/src/mac/nsToolkit.h b/widget/src/mac/nsToolkit.h index 2c893e77b10a..75c0737b7935 100644 --- a/widget/src/mac/nsToolkit.h +++ b/widget/src/mac/nsToolkit.h @@ -38,6 +38,8 @@ #ifndef TOOLKIT_H #define TOOLKIT_H +#include + #include "nsIToolkit.h" #include "nsRepeater.h" @@ -166,10 +168,11 @@ protected: Boolean RecoverMemoryReserve(Size reserveSize); + static pascal long GrowZoneProc(Size amountNeeded); + public: - static pascal long GrowZoneProc(Size amountNeeded); - + static Boolean EnsureMemoryCushion(); protected: