michael@0: /* vim:set ts=4 sw=4 sts=4 et cin: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsProxyRelease.h" michael@0: #include "nsThreadUtils.h" michael@0: #include "nsAutoPtr.h" michael@0: michael@0: class nsProxyReleaseEvent : public nsRunnable michael@0: { michael@0: public: michael@0: nsProxyReleaseEvent(nsISupports *doomed) michael@0: : mDoomed(doomed) { michael@0: } michael@0: michael@0: NS_IMETHOD Run() michael@0: { michael@0: mDoomed->Release(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: private: michael@0: nsISupports *mDoomed; michael@0: }; michael@0: michael@0: nsresult michael@0: NS_ProxyRelease(nsIEventTarget *target, nsISupports *doomed, michael@0: bool alwaysProxy) michael@0: { michael@0: nsresult rv; michael@0: michael@0: if (!doomed) { michael@0: // nothing to do michael@0: return NS_OK; michael@0: } michael@0: michael@0: if (!target) { michael@0: NS_RELEASE(doomed); michael@0: return NS_OK; michael@0: } michael@0: michael@0: if (!alwaysProxy) { michael@0: bool onCurrentThread = false; michael@0: rv = target->IsOnCurrentThread(&onCurrentThread); michael@0: if (NS_SUCCEEDED(rv) && onCurrentThread) { michael@0: NS_RELEASE(doomed); michael@0: return NS_OK; michael@0: } michael@0: } michael@0: michael@0: nsRefPtr ev = new nsProxyReleaseEvent(doomed); michael@0: if (!ev) { michael@0: // we do not release doomed here since it may cause a delete on the michael@0: // wrong thread. better to leak than crash. michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: } michael@0: michael@0: rv = target->Dispatch(ev, NS_DISPATCH_NORMAL); michael@0: if (NS_FAILED(rv)) { michael@0: NS_WARNING("failed to post proxy release event"); michael@0: // again, it is better to leak the doomed object than risk crashing as michael@0: // a result of deleting it on the wrong thread. michael@0: } michael@0: return rv; michael@0: }