зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1164581 - Adding an overload for NS_ProxyRelease that accepts already_AddRefed, and removing all the others. r=bobbyholley
This commit is contained in:
Родитель
590c6ec6dd
Коммит
686438c658
|
@ -49,17 +49,7 @@ ArchiveReaderEvent::ArchiveReaderEvent(ArchiveReader* aArchiveReader)
|
|||
ArchiveReaderEvent::~ArchiveReaderEvent()
|
||||
{
|
||||
if (!NS_IsMainThread()) {
|
||||
nsIMIMEService* mimeService;
|
||||
mMimeService.forget(&mimeService);
|
||||
|
||||
if (mimeService) {
|
||||
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
|
||||
NS_WARN_IF_FALSE(mainThread, "Couldn't get the main thread! Leaking!");
|
||||
|
||||
if (mainThread) {
|
||||
NS_ProxyRelease(mainThread, mimeService);
|
||||
}
|
||||
}
|
||||
NS_ReleaseOnMainThread(mMimeService.forget());
|
||||
}
|
||||
|
||||
MOZ_COUNT_DTOR(ArchiveReaderEvent);
|
||||
|
|
|
@ -778,11 +778,11 @@ Console::~Console()
|
|||
|
||||
if (!NS_IsMainThread()) {
|
||||
if (mStorage) {
|
||||
NS_ReleaseOnMainThread(mStorage);
|
||||
NS_ReleaseOnMainThread(mStorage.forget());
|
||||
}
|
||||
|
||||
if (mSandbox) {
|
||||
NS_ReleaseOnMainThread(mSandbox);
|
||||
NS_ReleaseOnMainThread(mSandbox.forget());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -629,8 +629,8 @@ WebSocketImpl::Disconnect()
|
|||
// until the end of the method.
|
||||
RefPtr<WebSocketImpl> kungfuDeathGrip = this;
|
||||
|
||||
NS_ReleaseOnMainThread(mChannel);
|
||||
NS_ReleaseOnMainThread(static_cast<nsIWebSocketEventService*>(mService.forget().take()));
|
||||
NS_ReleaseOnMainThread(mChannel.forget());
|
||||
NS_ReleaseOnMainThread(mService.forget());
|
||||
|
||||
mWebSocket->DontKeepAliveAnyMore();
|
||||
mWebSocket->mImpl = nullptr;
|
||||
|
|
|
@ -782,17 +782,8 @@ nsScriptLoader::ProcessOffThreadRequest(nsScriptLoadRequest* aRequest)
|
|||
NotifyOffThreadScriptLoadCompletedRunnable::~NotifyOffThreadScriptLoadCompletedRunnable()
|
||||
{
|
||||
if (MOZ_UNLIKELY(mRequest || mLoader) && !NS_IsMainThread()) {
|
||||
nsCOMPtr<nsIThread> mainThread;
|
||||
NS_GetMainThread(getter_AddRefs(mainThread));
|
||||
if (mainThread) {
|
||||
NS_ProxyRelease(mainThread, mRequest);
|
||||
NS_ProxyRelease(mainThread, mLoader);
|
||||
} else {
|
||||
MOZ_ASSERT(false, "We really shouldn't leak!");
|
||||
// Better to leak than crash.
|
||||
Unused << mRequest.forget();
|
||||
Unused << mLoader.forget();
|
||||
}
|
||||
NS_ReleaseOnMainThread(mRequest.forget());
|
||||
NS_ReleaseOnMainThread(mLoader.forget());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -62,10 +62,7 @@ ManagerId::~ManagerId()
|
|||
|
||||
// The PBackground worker thread shouldn't be running after the main thread
|
||||
// is stopped. So main thread is guaranteed to exist here.
|
||||
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
|
||||
MOZ_ASSERT(mainThread);
|
||||
|
||||
NS_ProxyRelease(mainThread, mPrincipal.forget().take());
|
||||
NS_ReleaseOnMainThread(mPrincipal.forget());
|
||||
}
|
||||
|
||||
} // namespace cache
|
||||
|
|
|
@ -860,7 +860,7 @@ DeviceStorageStatics::ListenerWrapper::ListenerWrapper(nsDOMDeviceStorage* aList
|
|||
DeviceStorageStatics::ListenerWrapper::~ListenerWrapper()
|
||||
{
|
||||
// Even weak pointers are not thread safe
|
||||
NS_ProxyRelease(mOwningThread, mListener);
|
||||
NS_ProxyRelease(mOwningThread, mListener.forget());
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -3716,8 +3716,7 @@ DeviceStorageRequestManager::~DeviceStorageRequestManager()
|
|||
while (i > 0) {
|
||||
--i;
|
||||
DS_LOG_ERROR("terminate %u", mPending[i].mId);
|
||||
NS_ProxyRelease(mOwningThread,
|
||||
NS_ISUPPORTS_CAST(EventTarget*, mPending[i].mRequest.forget().take()));
|
||||
NS_ProxyRelease(mOwningThread, mPending[i].mRequest.forget());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,10 +22,7 @@ SpeechStreamListener::~SpeechStreamListener()
|
|||
nsCOMPtr<nsIThread> mainThread;
|
||||
NS_GetMainThread(getter_AddRefs(mainThread));
|
||||
|
||||
SpeechRecognition* forgottenRecognition = nullptr;
|
||||
mRecognition.swap(forgottenRecognition);
|
||||
NS_ProxyRelease(mainThread,
|
||||
static_cast<DOMEventTargetHelper*>(forgottenRecognition));
|
||||
NS_ProxyRelease(mainThread, mRecognition.forget());
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -3626,17 +3626,8 @@ WorkerDebugger::~WorkerDebugger()
|
|||
MOZ_ASSERT(!mWorkerPrivate);
|
||||
|
||||
if (!NS_IsMainThread()) {
|
||||
nsCOMPtr<nsIThread> mainThread;
|
||||
if (NS_FAILED(NS_GetMainThread(getter_AddRefs(mainThread)))) {
|
||||
NS_WARNING("Failed to proxy release of listeners, leaking instead!");
|
||||
}
|
||||
|
||||
for (size_t index = 0; index < mListeners.Length(); ++index) {
|
||||
nsIWorkerDebuggerListener* listener = nullptr;
|
||||
mListeners[index].forget(&listener);
|
||||
if (NS_FAILED(NS_ProxyRelease(mainThread, listener))) {
|
||||
NS_WARNING("Failed to proxy release of listener, leaking instead!");
|
||||
}
|
||||
NS_ReleaseOnMainThread(mListeners[index].forget());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4158,11 +4149,7 @@ WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindowInner* aWindow,
|
|||
}
|
||||
|
||||
if (parentStatus > Running) {
|
||||
nsCOMPtr<nsIThread> mainThread;
|
||||
if (NS_FAILED(NS_GetMainThread(getter_AddRefs(mainThread))) ||
|
||||
NS_FAILED(NS_ProxyRelease(mainThread, loadInfo.mChannel))) {
|
||||
NS_WARNING("Failed to proxy release of channel, leaking instead!");
|
||||
}
|
||||
NS_ReleaseOnMainThread(loadInfo.mChannel.forget());
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
|
|
@ -615,17 +615,10 @@ nsGIOInputStream::Close()
|
|||
mDirListPtr = nullptr;
|
||||
}
|
||||
|
||||
if (mChannel)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (mChannel) {
|
||||
NS_ReleaseOnMainThread(dont_AddRef(mChannel));
|
||||
|
||||
nsCOMPtr<nsIThread> thread = do_GetMainThread();
|
||||
if (thread)
|
||||
rv = NS_ProxyRelease(thread, mChannel);
|
||||
|
||||
NS_ASSERTION(thread && NS_SUCCEEDED(rv), "leaking channel reference");
|
||||
mChannel = nullptr;
|
||||
(void) rv;
|
||||
}
|
||||
|
||||
mSpec.Truncate(); // free memory
|
||||
|
|
|
@ -65,16 +65,7 @@ public:
|
|||
mDict->SyncLoad();
|
||||
|
||||
// Release the dictionary on the main thread
|
||||
mozPersonalDictionary *dict;
|
||||
mDict.forget(&dict);
|
||||
|
||||
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
|
||||
if (mainThread) {
|
||||
NS_ProxyRelease(mainThread, static_cast<mozIPersonalDictionary *>(dict));
|
||||
} else {
|
||||
// It's better to leak the dictionary than to release it on a wrong thread
|
||||
NS_WARNING("Cannot get main thread, leaking mozPersonalDictionary.");
|
||||
}
|
||||
NS_ReleaseOnMainThread(mDict.forget());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -145,16 +136,8 @@ public:
|
|||
}
|
||||
|
||||
// Release the dictionary on the main thread.
|
||||
mozPersonalDictionary *dict;
|
||||
mDict.forget(&dict);
|
||||
NS_ReleaseOnMainThread(mDict.forget());
|
||||
|
||||
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
|
||||
if (mainThread) {
|
||||
NS_ProxyRelease(mainThread, static_cast<mozIPersonalDictionary *>(dict));
|
||||
} else {
|
||||
// It's better to leak the dictionary than to release it on a wrong thread.
|
||||
NS_WARNING("Cannot get main thread, leaking mozPersonalDictionary.");
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,16 +55,7 @@ Decoder::~Decoder()
|
|||
if (mImage && !NS_IsMainThread()) {
|
||||
// Dispatch mImage to main thread to prevent it from being destructed by the
|
||||
// decode thread.
|
||||
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
|
||||
NS_WARN_IF_FALSE(mainThread, "Couldn't get the main thread!");
|
||||
if (mainThread) {
|
||||
// Handle ambiguous nsISupports inheritance.
|
||||
RasterImage* rawImg = nullptr;
|
||||
mImage.swap(rawImg);
|
||||
DebugOnly<nsresult> rv =
|
||||
NS_ProxyRelease(mainThread, NS_ISUPPORTS_CAST(ImageResource*, rawImg));
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv), "Failed to proxy release to main thread");
|
||||
}
|
||||
NS_ReleaseOnMainThread(mImage.forget());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,12 +38,7 @@ nsIconChannel::nsIconChannel()
|
|||
nsIconChannel::~nsIconChannel()
|
||||
{
|
||||
if (mLoadInfo) {
|
||||
nsCOMPtr<nsIThread> mainThread;
|
||||
NS_GetMainThread(getter_AddRefs(mainThread));
|
||||
|
||||
nsILoadInfo* forgetableLoadInfo;
|
||||
mLoadInfo.forget(&forgetableLoadInfo);
|
||||
NS_ProxyRelease(mainThread, forgetableLoadInfo, false);
|
||||
NS_ReleaseOnMainThread(mLoadInfo.forget());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -76,12 +76,7 @@ nsIconChannel::nsIconChannel()
|
|||
nsIconChannel::~nsIconChannel()
|
||||
{
|
||||
if (mLoadInfo) {
|
||||
nsCOMPtr<nsIThread> mainThread;
|
||||
NS_GetMainThread(getter_AddRefs(mainThread));
|
||||
|
||||
nsILoadInfo* forgetableLoadInfo;
|
||||
mLoadInfo.forget(&forgetableLoadInfo);
|
||||
NS_ProxyRelease(mainThread, forgetableLoadInfo, false);
|
||||
NS_ReleaseOnMainThread(mLoadInfo.forget());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1129,10 +1129,7 @@ void
|
|||
PeerConnectionMedia::RemoveTransportFlow(int aIndex, bool aRtcp)
|
||||
{
|
||||
int index_inner = GetTransportFlowIndex(aIndex, aRtcp);
|
||||
TransportFlow* flow = mTransportFlows[index_inner].forget().take();
|
||||
if (flow) {
|
||||
NS_ProxyRelease(GetSTSThread(), flow);
|
||||
}
|
||||
NS_ProxyRelease(GetSTSThread(), mTransportFlows[index_inner].forget());
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -214,7 +214,7 @@ nsJARChannel::nsJARChannel()
|
|||
|
||||
nsJARChannel::~nsJARChannel()
|
||||
{
|
||||
NS_ReleaseOnMainThread(mLoadInfo);
|
||||
NS_ReleaseOnMainThread(mLoadInfo.forget());
|
||||
|
||||
// release owning reference to the jar handler
|
||||
nsJARProtocolHandler *handler = gJarHandler;
|
||||
|
|
|
@ -329,16 +329,14 @@ TLSServerConnectionInfo::~TLSServerConnectionInfo()
|
|||
return;
|
||||
}
|
||||
|
||||
nsITLSServerSecurityObserver* observer;
|
||||
RefPtr<nsITLSServerSecurityObserver> observer;
|
||||
{
|
||||
MutexAutoLock lock(mLock);
|
||||
mSecurityObserver.forget(&observer);
|
||||
observer = mSecurityObserver.forget();
|
||||
}
|
||||
|
||||
if (observer) {
|
||||
nsCOMPtr<nsIThread> mainThread;
|
||||
NS_GetMainThread(getter_AddRefs(mainThread));
|
||||
NS_ProxyRelease(mainThread, observer);
|
||||
NS_ReleaseOnMainThread(observer.forget());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ nsBaseChannel::nsBaseChannel()
|
|||
|
||||
nsBaseChannel::~nsBaseChannel()
|
||||
{
|
||||
NS_ReleaseOnMainThread(mLoadInfo);
|
||||
NS_ReleaseOnMainThread(mLoadInfo.forget());
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -128,31 +128,20 @@ private:
|
|||
// main thread to delete safely, but if this request had its
|
||||
// callbacks called normally they will all be null and this is a nop
|
||||
|
||||
nsCOMPtr<nsIThread> mainThread;
|
||||
NS_GetMainThread(getter_AddRefs(mainThread));
|
||||
|
||||
if (mChannel) {
|
||||
nsIChannel *forgettable;
|
||||
mChannel.forget(&forgettable);
|
||||
NS_ProxyRelease(mainThread, forgettable, false);
|
||||
NS_ReleaseOnMainThread(mChannel.forget());
|
||||
}
|
||||
|
||||
if (mCallback) {
|
||||
nsIProtocolProxyCallback *forgettable;
|
||||
mCallback.forget(&forgettable);
|
||||
NS_ProxyRelease(mainThread, forgettable, false);
|
||||
NS_ReleaseOnMainThread(mCallback.forget());
|
||||
}
|
||||
|
||||
if (mProxyInfo) {
|
||||
nsIProxyInfo *forgettable;
|
||||
mProxyInfo.forget(&forgettable);
|
||||
NS_ProxyRelease(mainThread, forgettable, false);
|
||||
NS_ReleaseOnMainThread(mProxyInfo.forget());
|
||||
}
|
||||
|
||||
if (mXPComPPS) {
|
||||
nsIProtocolProxyService *forgettable;
|
||||
mXPComPPS.forget(&forgettable);
|
||||
NS_ProxyRelease(mainThread, forgettable, false);
|
||||
NS_ReleaseOnMainThread(mXPComPPS.forget());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -233,15 +233,17 @@ nsServerSocket::OnSocketDetached(PRFileDesc *fd)
|
|||
mListener->OnStopListening(this, mCondition);
|
||||
|
||||
// need to atomically clear mListener. see our Close() method.
|
||||
nsIServerSocketListener *listener = nullptr;
|
||||
RefPtr<nsIServerSocketListener> listener = nullptr;
|
||||
{
|
||||
MutexAutoLock lock(mLock);
|
||||
mListener.swap(listener);
|
||||
listener = mListener.forget();
|
||||
}
|
||||
|
||||
// XXX we need to proxy the release to the listener's target thread to work
|
||||
// around bug 337492.
|
||||
if (listener)
|
||||
NS_ProxyRelease(mListenerTarget, listener);
|
||||
if (listener) {
|
||||
NS_ProxyRelease(mListenerTarget, listener.forget());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,12 +39,7 @@ nsStreamListenerTee::OnStopRequest(nsIRequest *request,
|
|||
|
||||
// release sink on the same thread where the data was written (bug 716293)
|
||||
if (mEventTarget) {
|
||||
nsIOutputStream *sink = nullptr;
|
||||
mSink.swap(sink);
|
||||
if (NS_FAILED(NS_ProxyRelease(mEventTarget, sink))) {
|
||||
NS_WARNING("Releasing sink on the current thread!");
|
||||
NS_RELEASE(sink);
|
||||
}
|
||||
NS_ProxyRelease(mEventTarget, mSink.forget());
|
||||
}
|
||||
else {
|
||||
mSink = 0;
|
||||
|
|
|
@ -37,7 +37,7 @@ private:
|
|||
{
|
||||
// our reference to mSink could be the last, so be sure to release
|
||||
// it on the target thread. otherwise, we could get into trouble.
|
||||
NS_ProxyRelease(mTarget, mSink);
|
||||
NS_ProxyRelease(mTarget, dont_AddRef(mSink));
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
|
@ -523,15 +523,15 @@ nsUDPSocket::OnSocketDetached(PRFileDesc *fd)
|
|||
if (mListener)
|
||||
{
|
||||
// need to atomically clear mListener. see our Close() method.
|
||||
nsCOMPtr<nsIUDPSocketListener> listener;
|
||||
RefPtr<nsIUDPSocketListener> listener = nullptr;
|
||||
{
|
||||
MutexAutoLock lock(mLock);
|
||||
mListener.swap(listener);
|
||||
listener = mListener.forget();
|
||||
}
|
||||
|
||||
if (listener) {
|
||||
listener->OnStopListening(this, mCondition);
|
||||
NS_ProxyRelease(mListenerTarget, listener);
|
||||
NS_ProxyRelease(mListenerTarget, listener.forget());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2691,7 +2691,7 @@ nsCacheService::ReleaseObject_Locked(nsISupports * obj,
|
|||
if (!target || (NS_SUCCEEDED(target->IsOnCurrentThread(&isCur)) && isCur)) {
|
||||
gService->mDoomedObjects.AppendElement(obj);
|
||||
} else {
|
||||
NS_ProxyRelease(target, obj);
|
||||
NS_ProxyRelease(target, dont_AddRef(obj));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1046,16 +1046,7 @@ private:
|
|||
: mObserver(aWeakObserver) { }
|
||||
virtual ~DiskConsumptionObserver() {
|
||||
if (mObserver && !NS_IsMainThread()) {
|
||||
nsIWeakReference *obs;
|
||||
mObserver.forget(&obs);
|
||||
|
||||
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
|
||||
if (mainThread) {
|
||||
NS_ProxyRelease(mainThread, obs);
|
||||
} else {
|
||||
NS_WARNING("Cannot get main thread, leaking weak reference to "
|
||||
"CacheStorageConsumptionObserver.");
|
||||
}
|
||||
NS_ReleaseOnMainThread(mObserver.forget());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -383,10 +383,7 @@ private:
|
|||
template<class T>
|
||||
void ProxyRelease(nsCOMPtr<T> &object, nsIThread* thread)
|
||||
{
|
||||
T* release;
|
||||
object.forget(&release);
|
||||
|
||||
NS_ProxyRelease(thread, release);
|
||||
NS_ProxyRelease(thread, object.forget());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
|
|
|
@ -107,35 +107,10 @@ RemoteOpenFileChild::~RemoteOpenFileChild()
|
|||
NotifyListener(NS_ERROR_UNEXPECTED);
|
||||
}
|
||||
} else {
|
||||
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
|
||||
if (mainThread) {
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_ProxyRelease(mainThread, mURI, true)));
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_ProxyRelease(mainThread, mAppURI, true)));
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_ProxyRelease(mainThread, mListener,
|
||||
true)));
|
||||
|
||||
TabChild* tabChild;
|
||||
mTabChild.forget(&tabChild);
|
||||
|
||||
if (tabChild) {
|
||||
nsCOMPtr<nsIRunnable> runnable =
|
||||
NS_NewNonOwningRunnableMethod(tabChild, &TabChild::Release);
|
||||
MOZ_ASSERT(runnable);
|
||||
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(mainThread->Dispatch(runnable,
|
||||
NS_DISPATCH_NORMAL)));
|
||||
}
|
||||
} else {
|
||||
using mozilla::Unused;
|
||||
|
||||
NS_WARNING("RemoteOpenFileChild released after thread shutdown, leaking "
|
||||
"its members!");
|
||||
|
||||
Unused << mURI.forget();
|
||||
Unused << mAppURI.forget();
|
||||
Unused << mListener.forget();
|
||||
Unused << mTabChild.forget();
|
||||
}
|
||||
NS_ReleaseOnMainThread(mURI.forget(), true);
|
||||
NS_ReleaseOnMainThread(mAppURI.forget(), true);
|
||||
NS_ReleaseOnMainThread(mListener.forget(), true);
|
||||
NS_ReleaseOnMainThread(mTabChild.forget(), true);
|
||||
}
|
||||
|
||||
if (mNSPRFileDesc) {
|
||||
|
|
|
@ -129,9 +129,7 @@ nsFileCopyEvent::DoCopy()
|
|||
|
||||
// Release the callback on the target thread to avoid destroying stuff on
|
||||
// the wrong thread.
|
||||
nsIRunnable *doomed = nullptr;
|
||||
mCallback.swap(doomed);
|
||||
NS_ProxyRelease(mCallbackTarget, doomed);
|
||||
NS_ProxyRelease(mCallbackTarget, mCallback.forget());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -127,7 +127,7 @@ HttpBaseChannel::~HttpBaseChannel()
|
|||
{
|
||||
LOG(("Destroying HttpBaseChannel @%x\n", this));
|
||||
|
||||
NS_ReleaseOnMainThread(mLoadInfo);
|
||||
NS_ReleaseOnMainThread(mLoadInfo.forget());
|
||||
|
||||
// Make sure we don't leak
|
||||
CleanRedirectCacheChainIfNecessary();
|
||||
|
|
|
@ -40,13 +40,8 @@ RtspControllerParent::Destroy()
|
|||
// RtspControllerParent is deleted. This ensures we only delete the
|
||||
// RtspControllerParent on the main thread.
|
||||
if (!NS_IsMainThread()) {
|
||||
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
|
||||
NS_ENSURE_TRUE_VOID(mainThread);
|
||||
RefPtr<RtspControllerParent> doomed(this);
|
||||
if (NS_FAILED(NS_ProxyRelease(mainThread,
|
||||
static_cast<nsIStreamingProtocolListener*>(doomed), true))) {
|
||||
NS_WARNING("Failed to proxy release to main thread!");
|
||||
}
|
||||
NS_ReleaseOnMainThread(doomed.forget(), true);
|
||||
} else {
|
||||
delete this;
|
||||
}
|
||||
|
|
|
@ -360,11 +360,8 @@ BaseWebSocketChannel::ListenerAndContextContainer::~ListenerAndContextContainer(
|
|||
{
|
||||
MOZ_ASSERT(mListener);
|
||||
|
||||
nsCOMPtr<nsIThread> mainThread;
|
||||
NS_GetMainThread(getter_AddRefs(mainThread));
|
||||
|
||||
NS_ProxyRelease(mainThread, mListener, false);
|
||||
NS_ProxyRelease(mainThread, mContext, false);
|
||||
NS_ReleaseOnMainThread(mListener.forget());
|
||||
NS_ReleaseOnMainThread(mContext.forget());
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
|
|
|
@ -1216,14 +1216,14 @@ WebSocketChannel::~WebSocketChannel()
|
|||
while ((mCurrentOut = (OutboundMessage *) mOutgoingMessages.PopFront()))
|
||||
delete mCurrentOut;
|
||||
|
||||
NS_ReleaseOnMainThread(mURI);
|
||||
NS_ReleaseOnMainThread(mOriginalURI);
|
||||
NS_ReleaseOnMainThread(mURI.forget());
|
||||
NS_ReleaseOnMainThread(mOriginalURI.forget());
|
||||
|
||||
mListenerMT = nullptr;
|
||||
|
||||
NS_ReleaseOnMainThread(mLoadGroup);
|
||||
NS_ReleaseOnMainThread(mLoadInfo);
|
||||
NS_ReleaseOnMainThread(static_cast<nsIWebSocketEventService*>(mService.forget().take()));
|
||||
NS_ReleaseOnMainThread(mLoadGroup.forget());
|
||||
NS_ReleaseOnMainThread(mLoadInfo.forget());
|
||||
NS_ReleaseOnMainThread(mService.forget());
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -56,12 +56,7 @@ WyciwygChannelChild::~WyciwygChannelChild()
|
|||
{
|
||||
LOG(("Destroying WyciwygChannelChild @%x\n", this));
|
||||
if (mLoadInfo) {
|
||||
nsCOMPtr<nsIThread> mainThread;
|
||||
NS_GetMainThread(getter_AddRefs(mainThread));
|
||||
|
||||
nsILoadInfo *forgetableLoadInfo;
|
||||
mLoadInfo.forget(&forgetableLoadInfo);
|
||||
NS_ProxyRelease(mainThread, forgetableLoadInfo, false);
|
||||
NS_ReleaseOnMainThread(mLoadInfo.forget());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,13 +40,7 @@ public:
|
|||
|
||||
~nsWyciwygAsyncEvent()
|
||||
{
|
||||
nsCOMPtr<nsIThread> thread = do_GetMainThread();
|
||||
NS_WARN_IF_FALSE(thread, "Couldn't get the main thread!");
|
||||
if (thread) {
|
||||
nsIWyciwygChannel *chan = static_cast<nsIWyciwygChannel *>(mChannel);
|
||||
mozilla::Unused << mChannel.forget();
|
||||
NS_ProxyRelease(thread, chan);
|
||||
}
|
||||
NS_ReleaseOnMainThread(mChannel.forget());
|
||||
}
|
||||
protected:
|
||||
RefPtr<nsWyciwygChannel> mChannel;
|
||||
|
@ -109,12 +103,7 @@ nsWyciwygChannel::nsWyciwygChannel()
|
|||
nsWyciwygChannel::~nsWyciwygChannel()
|
||||
{
|
||||
if (mLoadInfo) {
|
||||
nsCOMPtr<nsIThread> mainThread;
|
||||
NS_GetMainThread(getter_AddRefs(mainThread));
|
||||
|
||||
nsILoadInfo *forgetableLoadInfo;
|
||||
mLoadInfo.forget(&forgetableLoadInfo);
|
||||
NS_ProxyRelease(mainThread, forgetableLoadInfo, false);
|
||||
NS_ReleaseOnMainThread(mLoadInfo.forget(), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -196,7 +196,7 @@ DataChannelConnection::~DataChannelConnection()
|
|||
ASSERT_WEBRTC(NS_IsMainThread());
|
||||
if (mTransportFlow) {
|
||||
ASSERT_WEBRTC(mSTS);
|
||||
NS_ProxyRelease(mSTS, mTransportFlow);
|
||||
NS_ProxyRelease(mSTS, mTransportFlow.forget());
|
||||
}
|
||||
|
||||
if (mInternalIOThread) {
|
||||
|
@ -2417,7 +2417,7 @@ DataChannelConnection::ReadBlob(already_AddRefed<DataChannelConnection> aThis,
|
|||
// Bug 966602: Doesn't return an error to the caller via onerror.
|
||||
// We must release DataChannelConnection on MainThread to avoid issues (bug 876167)
|
||||
// aThis is now owned by the runnable; release it there
|
||||
NS_ProxyRelease(mainThread, runnable);
|
||||
NS_ProxyRelease(mainThread, runnable.forget());
|
||||
return;
|
||||
}
|
||||
aBlob->Close();
|
||||
|
|
|
@ -610,8 +610,7 @@ nsHTTPListener::~nsHTTPListener()
|
|||
}
|
||||
|
||||
if (mLoader) {
|
||||
nsCOMPtr<nsIThread> mainThread(do_GetMainThread());
|
||||
NS_ProxyRelease(mainThread, mLoader);
|
||||
NS_ReleaseOnMainThread(mLoader.forget());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -45,10 +45,12 @@ public:
|
|||
NS_IMETHOD Run()
|
||||
{
|
||||
if (mStatement->mAsyncStatement) {
|
||||
(void)::sqlite3_finalize(mStatement->mAsyncStatement);
|
||||
sqlite3_finalize(mStatement->mAsyncStatement);
|
||||
mStatement->mAsyncStatement = nullptr;
|
||||
}
|
||||
(void)::NS_ProxyRelease(mConnection->threadOpenedOn, mStatement);
|
||||
|
||||
nsCOMPtr<nsIThread> targetThread(mConnection->threadOpenedOn);
|
||||
NS_ProxyRelease(targetThread, mStatement.forget());
|
||||
return NS_OK;
|
||||
}
|
||||
private:
|
||||
|
@ -91,13 +93,8 @@ public:
|
|||
(void)::sqlite3_finalize(mAsyncStatement);
|
||||
mAsyncStatement = nullptr;
|
||||
|
||||
// Because of our ambiguous nsISupports we cannot use the NS_ProxyRelease
|
||||
// template helpers.
|
||||
Connection *rawConnection = nullptr;
|
||||
mConnection.swap(rawConnection);
|
||||
(void)::NS_ProxyRelease(
|
||||
rawConnection->threadOpenedOn,
|
||||
NS_ISUPPORTS_CAST(mozIStorageConnection *, rawConnection));
|
||||
nsCOMPtr<nsIThread> target(mConnection->threadOpenedOn);
|
||||
(void)::NS_ProxyRelease(target, mConnection.forget());
|
||||
return NS_OK;
|
||||
}
|
||||
private:
|
||||
|
|
|
@ -220,10 +220,8 @@ AsyncStatement::~AsyncStatement()
|
|||
if (!onCallingThread) {
|
||||
// NS_ProxyRelase only magic forgets for us if mDBConnection is an
|
||||
// nsCOMPtr. Which it is not; it's an nsRefPtr.
|
||||
Connection *forgottenConn = nullptr;
|
||||
mDBConnection.swap(forgottenConn);
|
||||
(void)::NS_ProxyRelease(forgottenConn->threadOpenedOn,
|
||||
static_cast<mozIStorageConnection *>(forgottenConn));
|
||||
nsCOMPtr<nsIThread> targetThread(mDBConnection->threadOpenedOn);
|
||||
NS_ProxyRelease(targetThread, mDBConnection.forget());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -382,15 +382,8 @@ public:
|
|||
}
|
||||
|
||||
~AsyncCloseConnection() {
|
||||
nsCOMPtr<nsIThread> thread;
|
||||
(void)NS_GetMainThread(getter_AddRefs(thread));
|
||||
// Handle ambiguous nsISupports inheritance.
|
||||
Connection *rawConnection = nullptr;
|
||||
mConnection.swap(rawConnection);
|
||||
(void)NS_ProxyRelease(thread,
|
||||
NS_ISUPPORTS_CAST(mozIStorageConnection *,
|
||||
rawConnection));
|
||||
(void)NS_ProxyRelease(thread, mCallbackEvent);
|
||||
NS_ReleaseOnMainThread(mConnection.forget());
|
||||
NS_ReleaseOnMainThread(mCallbackEvent.forget());
|
||||
}
|
||||
private:
|
||||
RefPtr<Connection> mConnection;
|
||||
|
@ -452,22 +445,13 @@ private:
|
|||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
// Handle ambiguous nsISupports inheritance.
|
||||
Connection *rawConnection = nullptr;
|
||||
mConnection.swap(rawConnection);
|
||||
(void)NS_ProxyRelease(thread, NS_ISUPPORTS_CAST(mozIStorageConnection *,
|
||||
rawConnection));
|
||||
|
||||
Connection *rawClone = nullptr;
|
||||
mClone.swap(rawClone);
|
||||
(void)NS_ProxyRelease(thread, NS_ISUPPORTS_CAST(mozIStorageConnection *,
|
||||
rawClone));
|
||||
NS_ProxyRelease(thread, mConnection.forget());
|
||||
NS_ProxyRelease(thread, mClone.forget());
|
||||
|
||||
// Generally, the callback will be released by CallbackComplete.
|
||||
// However, if for some reason Run() is not executed, we still
|
||||
// need to ensure that it is released here.
|
||||
mozIStorageCompletionCallback *rawCallback = nullptr;
|
||||
mCallback.swap(rawCallback);
|
||||
(void)NS_ProxyRelease(thread, rawCallback);
|
||||
NS_ProxyRelease(thread, mCallback.forget());
|
||||
}
|
||||
|
||||
RefPtr<Connection> mConnection;
|
||||
|
|
|
@ -332,8 +332,7 @@ Service::unregisterConnection(Connection *aConnection)
|
|||
// Ensure the connection is released on its opening thread. Note, we
|
||||
// must use .forget().take() so that we can manually cast to an
|
||||
// unambiguous nsISupports type.
|
||||
NS_ProxyRelease(thread,
|
||||
static_cast<mozIStorageConnection*>(mConnections[i].forget().take()));
|
||||
NS_ProxyRelease(thread, mConnections[i].forget());
|
||||
|
||||
mConnections.RemoveElementAt(i);
|
||||
return;
|
||||
|
@ -733,23 +732,13 @@ private:
|
|||
|
||||
~AsyncInitDatabase()
|
||||
{
|
||||
nsCOMPtr<nsIThread> thread;
|
||||
DebugOnly<nsresult> rv = NS_GetMainThread(getter_AddRefs(thread));
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
(void)NS_ProxyRelease(thread, mStorageFile);
|
||||
|
||||
// Handle ambiguous nsISupports inheritance.
|
||||
Connection *rawConnection = nullptr;
|
||||
mConnection.swap(rawConnection);
|
||||
(void)NS_ProxyRelease(thread, NS_ISUPPORTS_CAST(mozIStorageConnection *,
|
||||
rawConnection));
|
||||
NS_ReleaseOnMainThread(mStorageFile.forget());
|
||||
NS_ReleaseOnMainThread(mConnection.forget());
|
||||
|
||||
// Generally, the callback will be released by CallbackComplete.
|
||||
// However, if for some reason Run() is not executed, we still
|
||||
// need to ensure that it is released here.
|
||||
mozIStorageCompletionCallback *rawCallback = nullptr;
|
||||
mCallback.swap(rawCallback);
|
||||
(void)NS_ProxyRelease(thread, rawCallback);
|
||||
NS_ReleaseOnMainThread(mCallback.forget());
|
||||
}
|
||||
|
||||
RefPtr<Connection> mConnection;
|
||||
|
|
|
@ -52,8 +52,7 @@ public:
|
|||
// We need to ensure that mParamsArray is released on the main thread,
|
||||
// as the binding arguments may be XPConnect values, which are safe
|
||||
// to release only on the main thread.
|
||||
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
|
||||
(void)NS_ProxyRelease(mainThread, mParamsArray);
|
||||
NS_ReleaseOnMainThread(mParamsArray.forget());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -529,8 +529,7 @@ public:
|
|||
// Last ditch attempt to release on the main thread - some of
|
||||
// the members of event are not thread-safe, so letting the
|
||||
// pointer go out of scope would cause a crash.
|
||||
nsCOMPtr<nsIThread> main = do_GetMainThread();
|
||||
NS_ProxyRelease(main, event);
|
||||
NS_ReleaseOnMainThread(event.forget());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -547,8 +546,7 @@ public:
|
|||
// Last ditch attempt to release on the main thread - some of
|
||||
// the members of event are not thread-safe, so letting the
|
||||
// pointer go out of scope would cause a crash.
|
||||
nsCOMPtr<nsIThread> main = do_GetMainThread();
|
||||
NS_ProxyRelease(main, event);
|
||||
NS_ReleaseOnMainThread(event.forget());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -749,8 +747,7 @@ public:
|
|||
if (!mResult) {
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsIThread> main = do_GetMainThread();
|
||||
(void)NS_ProxyRelease(main, mResult);
|
||||
NS_ReleaseOnMainThread(mResult.forget());
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -787,8 +784,7 @@ public:
|
|||
if (!mResult) {
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsIThread> main = do_GetMainThread();
|
||||
(void)NS_ProxyRelease(main, mResult);
|
||||
NS_ReleaseOnMainThread(mResult.forget());
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -357,10 +357,8 @@ AsyncFaviconHelperBase::AsyncFaviconHelperBase(
|
|||
|
||||
AsyncFaviconHelperBase::~AsyncFaviconHelperBase()
|
||||
{
|
||||
nsCOMPtr<nsIThread> thread;
|
||||
(void)NS_GetMainThread(getter_AddRefs(thread));
|
||||
if (mCallback) {
|
||||
(void)NS_ProxyRelease(thread, mCallback, true);
|
||||
NS_ReleaseOnMainThread(mCallback.forget(), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -543,13 +543,9 @@ DatabaseShutdown::Complete(nsresult, nsISupports*)
|
|||
if (NS_WARN_IF(!mBarrier)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
nsCOMPtr<nsIAsyncShutdownBarrier> barrier = mBarrier.forget();
|
||||
nsCOMPtr<nsIAsyncShutdownClient> parentClient = mParentClient.forget();
|
||||
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
|
||||
MOZ_ASSERT(mainThread);
|
||||
|
||||
NS_ProxyRelease(mainThread, barrier);
|
||||
NS_ProxyRelease(mainThread, parentClient);
|
||||
NS_ReleaseOnMainThread(mBarrier.forget());
|
||||
NS_ReleaseOnMainThread(mParentClient.forget());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -196,7 +196,7 @@ public:
|
|||
{
|
||||
mStatementCache.FinalizeStatements();
|
||||
// Release the owner back on the calling thread.
|
||||
(void)NS_ProxyRelease(mCallingThread, mOwner);
|
||||
NS_ProxyRelease(mCallingThread, mOwner.forget());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -798,11 +798,8 @@ NS_IMPL_ISUPPORTS(nsUrlClassifierLookupCallback,
|
|||
|
||||
nsUrlClassifierLookupCallback::~nsUrlClassifierLookupCallback()
|
||||
{
|
||||
nsCOMPtr<nsIThread> thread;
|
||||
(void)NS_GetMainThread(getter_AddRefs(thread));
|
||||
|
||||
if (mCallback) {
|
||||
(void)NS_ProxyRelease(thread, mCallback, false);
|
||||
NS_ReleaseOnMainThread(mCallback.forget());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -736,7 +736,7 @@ nsScreenGonk::UpdateMirroringWidget(already_AddRefed<nsWindow>& aWindow)
|
|||
|
||||
if (mMirroringWidget) {
|
||||
nsCOMPtr<nsIWidget> widget = mMirroringWidget.forget();
|
||||
NS_ReleaseOnMainThread(widget);
|
||||
NS_ReleaseOnMainThread(widget.forget());
|
||||
}
|
||||
mMirroringWidget = aWindow;
|
||||
}
|
||||
|
|
|
@ -314,7 +314,7 @@ nsConsoleService::LogMessageWithMode(nsIConsoleMessage* aMessage,
|
|||
// Release |retiredMessage| on the main thread in case it is an instance of
|
||||
// a mainthread-only class like nsScriptErrorWithStack and we're off the
|
||||
// main thread.
|
||||
NS_ReleaseOnMainThread(retiredMessage);
|
||||
NS_ReleaseOnMainThread(retiredMessage.forget());
|
||||
}
|
||||
|
||||
if (r) {
|
||||
|
|
|
@ -54,16 +54,8 @@ nsInterfaceRequestorAgg::GetInterface(const nsIID& aIID, void** aResult)
|
|||
|
||||
nsInterfaceRequestorAgg::~nsInterfaceRequestorAgg()
|
||||
{
|
||||
nsIInterfaceRequestor* iir = nullptr;
|
||||
mFirst.swap(iir);
|
||||
if (iir) {
|
||||
NS_ProxyRelease(mConsumerTarget, iir);
|
||||
}
|
||||
iir = nullptr;
|
||||
mSecond.swap(iir);
|
||||
if (iir) {
|
||||
NS_ProxyRelease(mConsumerTarget, iir);
|
||||
}
|
||||
NS_ProxyRelease(mConsumerTarget, mFirst.forget());
|
||||
NS_ProxyRelease(mConsumerTarget, mSecond.forget());
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsProxyRelease.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
class nsProxyReleaseEvent : public nsRunnable
|
||||
{
|
||||
public:
|
||||
explicit nsProxyReleaseEvent(nsISupports* aDoomed) : mDoomed(aDoomed) {}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
mDoomed->Release();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsISupports* MOZ_OWNING_REF mDoomed;
|
||||
};
|
||||
|
||||
nsresult
|
||||
NS_ProxyRelease(nsIEventTarget* aTarget, nsISupports* aDoomed,
|
||||
bool aAlwaysProxy)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (!aDoomed) {
|
||||
// nothing to do
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!aTarget) {
|
||||
NS_RELEASE(aDoomed);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!aAlwaysProxy) {
|
||||
bool onCurrentThread = false;
|
||||
rv = aTarget->IsOnCurrentThread(&onCurrentThread);
|
||||
if (NS_SUCCEEDED(rv) && onCurrentThread) {
|
||||
NS_RELEASE(aDoomed);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> ev = new nsProxyReleaseEvent(aDoomed);
|
||||
if (!ev) {
|
||||
// we do not release aDoomed here since it may cause a delete on the
|
||||
// wrong thread. better to leak than crash.
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
rv = aTarget->Dispatch(ev, NS_DISPATCH_NORMAL);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("failed to post proxy release event");
|
||||
// again, it is better to leak the aDoomed object than risk crashing as
|
||||
// a result of deleting it on the wrong thread.
|
||||
}
|
||||
return rv;
|
||||
}
|
|
@ -12,44 +12,34 @@
|
|||
#include "nsCOMPtr.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "MainThreadUtils.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "mozilla/Likely.h"
|
||||
#include "mozilla/Move.h"
|
||||
|
||||
#ifdef XPCOM_GLUE_AVOID_NSPR
|
||||
#error NS_ProxyRelease implementation depends on NSPR.
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Ensure that a nsCOMPtr is released on the target thread.
|
||||
*
|
||||
* @see NS_ProxyRelease(nsIEventTarget*, nsISupports*, bool)
|
||||
*/
|
||||
|
||||
template<class T>
|
||||
inline NS_HIDDEN_(nsresult)
|
||||
NS_ProxyRelease(nsIEventTarget* aTarget, nsCOMPtr<T>& aDoomed,
|
||||
bool aAlwaysProxy = false)
|
||||
class nsProxyReleaseEvent : public nsRunnable
|
||||
{
|
||||
T* raw = nullptr;
|
||||
aDoomed.swap(raw);
|
||||
return NS_ProxyRelease(aTarget, raw, aAlwaysProxy);
|
||||
}
|
||||
public:
|
||||
explicit nsProxyReleaseEvent(already_AddRefed<T> aDoomed)
|
||||
: mDoomed(aDoomed.take()) {}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
NS_IF_RELEASE(mDoomed);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
T* MOZ_OWNING_REF mDoomed;
|
||||
};
|
||||
|
||||
/**
|
||||
* Ensure that a nsRefPtr is released on the target thread.
|
||||
*
|
||||
* @see NS_ProxyRelease(nsIEventTarget*, nsISupports*, bool)
|
||||
*/
|
||||
template<class T>
|
||||
inline NS_HIDDEN_(nsresult)
|
||||
NS_ProxyRelease(nsIEventTarget* aTarget, RefPtr<T>& aDoomed,
|
||||
bool aAlwaysProxy = false)
|
||||
{
|
||||
T* raw = nullptr;
|
||||
aDoomed.swap(raw);
|
||||
return NS_ProxyRelease(aTarget, raw, aAlwaysProxy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the delete of a nsISupports object occurs on the target thread.
|
||||
* Ensures that the delete of a smart pointer occurs on the target thread.
|
||||
*
|
||||
* @param aTarget
|
||||
* the target thread where the doomed object should be released.
|
||||
|
@ -61,42 +51,39 @@ NS_ProxyRelease(nsIEventTarget* aTarget, RefPtr<T>& aDoomed,
|
|||
* true, then an event will always be posted to the target thread for
|
||||
* asynchronous release.
|
||||
*/
|
||||
nsresult
|
||||
NS_ProxyRelease(nsIEventTarget* aTarget, nsISupports* aDoomed,
|
||||
bool aAlwaysProxy = false);
|
||||
|
||||
/**
|
||||
* Ensure that a nsCOMPtr is released on the main thread.
|
||||
*
|
||||
* @see NS_ReleaseOnMainThread( nsISupports*, bool)
|
||||
*/
|
||||
template<class T>
|
||||
inline NS_HIDDEN_(nsresult)
|
||||
NS_ReleaseOnMainThread(nsCOMPtr<T>& aDoomed,
|
||||
bool aAlwaysProxy = false)
|
||||
inline NS_HIDDEN_(void)
|
||||
NS_ProxyRelease(nsIEventTarget* aTarget, already_AddRefed<T> aDoomed,
|
||||
bool aAlwaysProxy = false)
|
||||
{
|
||||
T* raw = nullptr;
|
||||
aDoomed.swap(raw);
|
||||
return NS_ReleaseOnMainThread(raw, aAlwaysProxy);
|
||||
// Auto-managing release of the pointer.
|
||||
RefPtr<T> doomed = aDoomed;
|
||||
nsresult rv;
|
||||
|
||||
if (!doomed || !aTarget) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!aAlwaysProxy) {
|
||||
bool onCurrentThread = false;
|
||||
rv = aTarget->IsOnCurrentThread(&onCurrentThread);
|
||||
if (NS_SUCCEEDED(rv) && onCurrentThread) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> ev = new nsProxyReleaseEvent<T>(doomed.forget());
|
||||
|
||||
rv = aTarget->Dispatch(ev, NS_DISPATCH_NORMAL);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("failed to post proxy release event, leaking!");
|
||||
// It is better to leak the aDoomed object than risk crashing as
|
||||
// a result of deleting it on the wrong thread.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that a nsRefPtr is released on the main thread.
|
||||
*
|
||||
* @see NS_ReleaseOnMainThread(nsISupports*, bool)
|
||||
*/
|
||||
template<class T>
|
||||
inline NS_HIDDEN_(nsresult)
|
||||
NS_ReleaseOnMainThread(RefPtr<T>& aDoomed,
|
||||
bool aAlwaysProxy = false)
|
||||
{
|
||||
T* raw = nullptr;
|
||||
aDoomed.swap(raw);
|
||||
return NS_ReleaseOnMainThread(raw, aAlwaysProxy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the delete of a nsISupports object occurs on the main thread.
|
||||
* Ensures that the delete of a smart pointer occurs on the main thread.
|
||||
*
|
||||
* @param aDoomed
|
||||
* the doomed object; the object to be released on the main thread.
|
||||
|
@ -106,8 +93,9 @@ NS_ReleaseOnMainThread(RefPtr<T>& aDoomed,
|
|||
* parameter is true, then an event will always be posted to the main
|
||||
* thread for asynchronous release.
|
||||
*/
|
||||
inline nsresult
|
||||
NS_ReleaseOnMainThread(nsISupports* aDoomed,
|
||||
template<class T>
|
||||
inline NS_HIDDEN_(void)
|
||||
NS_ReleaseOnMainThread(already_AddRefed<T> aDoomed,
|
||||
bool aAlwaysProxy = false)
|
||||
{
|
||||
// NS_ProxyRelease treats a null event target as "the current thread". So a
|
||||
|
@ -115,10 +103,15 @@ NS_ReleaseOnMainThread(nsISupports* aDoomed,
|
|||
// main thread or the release must happen asynchronously.
|
||||
nsCOMPtr<nsIThread> mainThread;
|
||||
if (!NS_IsMainThread() || aAlwaysProxy) {
|
||||
NS_GetMainThread(getter_AddRefs(mainThread));
|
||||
nsresult rv = NS_GetMainThread(getter_AddRefs(mainThread));
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Could not get main thread! Leaking.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_ProxyRelease(mainThread, aDoomed, aAlwaysProxy);
|
||||
NS_ProxyRelease(mainThread, mozilla::Move(aDoomed), aAlwaysProxy);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -185,13 +178,7 @@ private:
|
|||
if (NS_IsMainThread()) {
|
||||
NS_IF_RELEASE(mRawPtr);
|
||||
} else if (mRawPtr) {
|
||||
nsCOMPtr<nsIThread> mainThread;
|
||||
NS_GetMainThread(getter_AddRefs(mainThread));
|
||||
if (!mainThread) {
|
||||
NS_WARNING("Couldn't get main thread! Leaking pointer.");
|
||||
return;
|
||||
}
|
||||
NS_ProxyRelease(mainThread, mRawPtr);
|
||||
NS_ReleaseOnMainThread(dont_AddRef(mRawPtr));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,6 @@ xpcom_glue_src_cppsrcs = [
|
|||
xpcom_gluens_src_lcppsrcs = [
|
||||
'BlockingResourceBase.cpp',
|
||||
'GenericFactory.cpp',
|
||||
'nsProxyRelease.cpp',
|
||||
'nsTextFormatter.cpp',
|
||||
]
|
||||
|
||||
|
|
|
@ -61,7 +61,6 @@ xpcom_glue_src = [
|
|||
'nsID.cpp',
|
||||
'nsISupportsImpl.cpp',
|
||||
'nsMemory.cpp',
|
||||
'nsProxyRelease.cpp',
|
||||
'nsQuickSort.cpp',
|
||||
'nsTArray.cpp',
|
||||
'nsTObserverArray.cpp',
|
||||
|
|
Загрузка…
Ссылка в новой задаче