diff options
Diffstat (limited to 'src/libs/xpcom18a4/xpcom/proxy/src/nsProxyRelease.cpp')
-rw-r--r-- | src/libs/xpcom18a4/xpcom/proxy/src/nsProxyRelease.cpp | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/src/libs/xpcom18a4/xpcom/proxy/src/nsProxyRelease.cpp b/src/libs/xpcom18a4/xpcom/proxy/src/nsProxyRelease.cpp new file mode 100644 index 00000000..3ceeb667 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/proxy/src/nsProxyRelease.cpp @@ -0,0 +1,55 @@ +#include "nsProxyRelease.h" + +PR_STATIC_CALLBACK(void*) +HandleProxyReleaseEvent(PLEvent *self) +{ + nsISupports* owner = (nsISupports*) self->owner; + NS_RELEASE(owner); + return nsnull; +} + +PR_STATIC_CALLBACK(void) +DestroyProxyReleaseEvent(PLEvent *self) +{ + delete self; +} + +NS_COM nsresult +NS_ProxyRelease(nsIEventTarget *target, nsISupports *doomed, PRBool alwaysProxy) +{ + nsresult rv; + + if (!target) { + NS_RELEASE(doomed); + return NS_OK; + } + + if (!alwaysProxy) { + PRBool onCurrentThread = PR_FALSE; + rv = target->IsOnCurrentThread(&onCurrentThread); + if (NS_SUCCEEDED(rv) && onCurrentThread) { + NS_RELEASE(doomed); + return NS_OK; + } + } + + PLEvent *ev = new PLEvent; + if (!ev) { + // we do not release doomed here since it may cause a delete on the + // wrong thread. better to leak than crash. + return NS_ERROR_OUT_OF_MEMORY; + } + + PL_InitEvent(ev, doomed, + HandleProxyReleaseEvent, + DestroyProxyReleaseEvent); + + rv = target->PostEvent(ev); + if (NS_FAILED(rv)) { + NS_WARNING("failed to post proxy release event"); + PL_DestroyEvent(ev); + // again, it is better to leak the doomed object than risk crashing as + // a result of deleting it on the wrong thread. + } + return rv; +} |