summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMoonchild <moonchild@palemoon.org>2022-01-14 20:16:45 +0000
committerMoonchild <moonchild@palemoon.org>2022-04-08 15:03:12 +0200
commit2829b9387bf76818ca73e501f2801287380ae8a8 (patch)
treefa39a56bafe06730985fb0eb2ea953502d54440f
parent1e1a1e5c711565e4d1abea0951432d6539c629b7 (diff)
downloaduxp-2829b9387bf76818ca73e501f2801287380ae8a8.tar.gz
[interface] Hold a self-reference in nsDataObj.
-rw-r--r--widget/windows/nsDataObj.cpp20
-rw-r--r--widget/windows/nsDataObj.h1
2 files changed, 21 insertions, 0 deletions
diff --git a/widget/windows/nsDataObj.cpp b/widget/windows/nsDataObj.cpp
index 80abf35218..39b269d0db 100644
--- a/widget/windows/nsDataObj.cpp
+++ b/widget/windows/nsDataObj.cpp
@@ -24,6 +24,7 @@
#include "nsIURL.h"
#include "nsNetUtil.h"
#include "mozilla/Services.h"
+#include "nsProxyRelease.h"
#include "nsIOutputStream.h"
#include "nsXPCOMStrings.h"
#include "nscore.h"
@@ -442,6 +443,12 @@ STDMETHODIMP_(ULONG) nsDataObj::AddRef()
{
++m_cRef;
NS_LOG_ADDREF(this, m_cRef, "nsDataObj", sizeof(*this));
+
+ // When the first reference is taken, hold our own internal reference.
+ if (m_cRef == 1) {
+ mKeepAlive = this;
+ }
+
return m_cRef;
}
@@ -528,6 +535,12 @@ STDMETHODIMP_(ULONG) nsDataObj::Release()
--m_cRef;
NS_LOG_RELEASE(this, m_cRef, "nsDataObj");
+
+ // If we hold the last reference, submit release of it to the main thread.
+ if (m_cRef == 1 && mKeepAlive) {
+ NS_ReleaseOnMainThread(mKeepAlive.forget(), true);
+ }
+
if (0 != m_cRef)
return m_cRef;
@@ -542,6 +555,10 @@ STDMETHODIMP_(ULONG) nsDataObj::Release()
helper->Attach();
}
+ // In case the destructor ever AddRef/Releases, ensure we don't delete twice
+ // or take mKeepAlive as another reference.
+ m_cRef = 1;
+
delete this;
return 0;
@@ -567,6 +584,9 @@ STDMETHODIMP nsDataObj::GetData(LPFORMATETC aFormat, LPSTGMEDIUM pSTM)
if (!mTransferable)
return DV_E_FORMATETC;
+ // Hold an extra reference in case we end up spinning the event loop.
+ RefPtr<nsDataObj> keepAliveDuringGetData(this);
+
uint32_t dfInx = 0;
static CLIPFORMAT fileDescriptorFlavorA = ::RegisterClipboardFormat( CFSTR_FILEDESCRIPTORA );
diff --git a/widget/windows/nsDataObj.h b/widget/windows/nsDataObj.h
index 61f209e857..8dabce7b8a 100644
--- a/widget/windows/nsDataObj.h
+++ b/widget/windows/nsDataObj.h
@@ -228,6 +228,7 @@ protected:
// nsDataObj owns and ref counts CEnumFormatEtc,
nsCOMPtr<nsIFile> mCachedTempFile;
+ RefPtr<nsDataObj> mKeepAlive;
BOOL mIsAsyncMode;
BOOL mIsInOperation;