Bug 1164581 - Adding an overload for NS_ProxyRelease that accepts already_AddRefed, and removing all the others. r=bobbyholley

This commit is contained in:
Aidin Gharibnavaz 2016-02-10 08:23:00 +01:00
Родитель 590c6ec6dd
Коммит 686438c658
53 изменённых файлов: 152 добавлений и 451 удалений

Просмотреть файл

@ -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());
}
}

5
dom/cache/ManagerId.cpp поставляемый
Просмотреть файл

@ -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());
}
}
}

2
netwerk/cache/nsCacheService.cpp поставляемый
Просмотреть файл

@ -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',