summaryrefslogtreecommitdiffstats
path: root/src/libs/xpcom18a4/xpcom/proxy/src/nsProxyRelease.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/xpcom18a4/xpcom/proxy/src/nsProxyRelease.cpp')
-rw-r--r--src/libs/xpcom18a4/xpcom/proxy/src/nsProxyRelease.cpp55
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;
+}