Bug 593530 - Don't leak the DeviceManagerD3D9 if initializing it fails. r=joe a=blocking2.0:beta6+
authorMatt Woodrow <mwoodrow@mozilla.com>
Fri, 03 Sep 2010 23:21:26 -0400
changeset 51996 4051f53e800780178bb7afeca9ace90167d2520e
parent 51995 6d1ca8f869dd18cf28832dae1c14de4ce60b9801
child 51997 c31b8f10cbaf95daf34ffd47b0723f2c26f1c34a
push idunknown
push userunknown
push dateunknown
reviewersjoe, blocking2
bugs593530
milestone2.0b6pre
Bug 593530 - Don't leak the DeviceManagerD3D9 if initializing it fails. r=joe a=blocking2.0:beta6+
gfx/layers/d3d9/DeviceManagerD3D9.cpp
gfx/layers/d3d9/DeviceManagerD3D9.h
gfx/layers/d3d9/LayerManagerD3D9.cpp
--- a/gfx/layers/d3d9/DeviceManagerD3D9.cpp
+++ b/gfx/layers/d3d9/DeviceManagerD3D9.cpp
@@ -184,16 +184,19 @@ DeviceManagerD3D9::DeviceManagerD3D9()
 {
 }
 
 DeviceManagerD3D9::~DeviceManagerD3D9()
 {
   LayerManagerD3D9::OnDeviceManagerDestroy(this);
 }
 
+NS_IMPL_ADDREF(DeviceManagerD3D9)
+NS_IMPL_RELEASE(DeviceManagerD3D9)
+
 bool
 DeviceManagerD3D9::Init()
 {
   WNDCLASSW wc;
   HRESULT hr;
 
   if (!GetClassInfoW(GetModuleHandle(NULL), kClassName, &wc)) {
       ZeroMemory(&wc, sizeof(WNDCLASSW));
--- a/gfx/layers/d3d9/DeviceManagerD3D9.h
+++ b/gfx/layers/d3d9/DeviceManagerD3D9.h
@@ -101,19 +101,23 @@ private:
  * Device manager, this class is used by the layer managers to share the D3D9
  * device and create swap chains for the individual windows the layer managers
  * belong to.
  */
 class THEBES_API DeviceManagerD3D9
 {
 public:
   DeviceManagerD3D9();
+  NS_IMETHOD_(nsrefcnt) AddRef(void);
+  NS_IMETHOD_(nsrefcnt) Release(void);
+protected:
+  nsAutoRefCnt mRefCnt;
+  NS_DECL_OWNINGTHREAD
 
-  NS_INLINE_DECL_REFCOUNTING(DeviceManagerD3D9)
-
+public:
   bool Init();
 
   /**
    * Sets up the render state for the device for layer rendering.
    */
   void SetupRenderState();
 
   /**
--- a/gfx/layers/d3d9/LayerManagerD3D9.cpp
+++ b/gfx/layers/d3d9/LayerManagerD3D9.cpp
@@ -60,39 +60,41 @@ LayerManagerD3D9::LayerManagerD3D9(nsIWi
 
 LayerManagerD3D9::~LayerManagerD3D9()
 {
   /* Important to release this first since it also holds a reference to the
    * device manager
    */
   mSwapChain = nsnull;
 
-  if (mDeviceManager) {
-    mDeviceManager->Release();
+  if (mDeviceManager && mDeviceManager->Release() == 0) {
+    mDeviceManager = nsnull;
   }
 }
 
 PRBool
 LayerManagerD3D9::Initialize()
 {
   /* Check the user preference for whether 3d video is enabled or not */ 
   nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID); 
   prefs->GetBoolPref("gfx.3d_video.enabled", &mIs3DEnabled); 
 
   if (!mDeviceManager) {
     mDeviceManager = new DeviceManagerD3D9;
+    mDeviceManager->AddRef();
 
     if (!mDeviceManager->Init()) {
+      mDeviceManager->Release();
       mDeviceManager = nsnull;
       return PR_FALSE;
     }
+  } else {
+    mDeviceManager->AddRef();
   }
 
-  mDeviceManager->AddRef();
-
   mSwapChain = mDeviceManager->
     CreateSwapChain((HWND)mWidget->GetNativeData(NS_NATIVE_WINDOW));
 
   if (!mSwapChain) {
     return PR_FALSE;
   }
 
   return PR_TRUE;