diff options
author | Moonchild <moonchild@palemoon.org> | 2022-01-14 20:16:45 +0000 |
---|---|---|
committer | Moonchild <moonchild@palemoon.org> | 2022-04-08 15:03:12 +0200 |
commit | 2829b9387bf76818ca73e501f2801287380ae8a8 (patch) | |
tree | fa39a56bafe06730985fb0eb2ea953502d54440f /widget | |
parent | 1e1a1e5c711565e4d1abea0951432d6539c629b7 (diff) | |
download | uxp-2829b9387bf76818ca73e501f2801287380ae8a8.tar.gz |
[interface] Hold a self-reference in nsDataObj.
Diffstat (limited to 'widget')
-rw-r--r-- | widget/windows/nsDataObj.cpp | 20 | ||||
-rw-r--r-- | widget/windows/nsDataObj.h | 1 |
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; |