Bug 1171716 - Part 1: Add NS_ReleaseOnMainThread. r=froydnj
☠☠ backed out by f7acbdc32c61 ☠ ☠
authorEric Rahm <erahm@mozilla.com>
Tue, 09 Jun 2015 18:25:43 -0700
changeset 271003 f75717d3eba012a76cabe0a5aa512320b9f8f6d8
parent 271002 a7d7921c934544346369fa6832bf57191de77503
child 271004 be499a3cae5d741b7a1a1ca5fc8b91fc0cdf6d68
push id2738
push userwcosta@mozilla.com
push dateWed, 10 Jun 2015 13:39:02 +0000
reviewersfroydnj
bugs1171716
milestone41.0a1
Bug 1171716 - Part 1: Add NS_ReleaseOnMainThread. r=froydnj
xpcom/glue/nsProxyRelease.h
--- a/xpcom/glue/nsProxyRelease.h
+++ b/xpcom/glue/nsProxyRelease.h
@@ -52,25 +52,81 @@ NS_ProxyRelease(nsIEventTarget* aTarget,
  * Ensures that the delete of a nsISupports object occurs on the target thread.
  *
  * @param aTarget
  *        the target thread where the doomed object should be released.
  * @param aDoomed
  *        the doomed object; the object to be released on the target thread.
  * @param aAlwaysProxy
  *        normally, if NS_ProxyRelease is called on the target thread, then the
- *        doomed object will released directly.  however, if this parameter is
+ *        doomed object will be released directly. However, if this parameter is
  *        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)
+{
+  T* raw = nullptr;
+  aDoomed.swap(raw);
+  return NS_ReleaseOnMainThread(raw, aAlwaysProxy);
+}
+
+/**
+ * Ensure that a nsRefPtr is released on the main thread.
+ *
+ * @see NS_ReleaseOnMainThread(nsISupports*, bool)
+ */
+template<class T>
+inline NS_HIDDEN_(nsresult)
+NS_ReleaseOnMainThread(nsRefPtr<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.
+ *
+ * @param aDoomed
+ *        the doomed object; the object to be released on the main thread.
+ * @param aAlwaysProxy
+ *        normally, if NS_ReleaseOnMainThread is called on the main thread,
+ *        then the doomed object will be released directly. However, if this
+ *        parameter is true, then an event will always be posted to the main
+ *        thread for asynchronous release.
+ */
+nsresult
+NS_ReleaseOnMainThread(nsISupports* aDoomed,
+                       bool aAlwaysProxy = false)
+{
+  // NS_ProxyRelease treats a null event target as "the current thread".  So a
+  // handle on the main thread is only necessary when we're not already on the
+  // main thread or the release must happen asynchronously.
+  nsCOMPtr<nsIThread> mainThread;
+  if (!NS_IsMainThread() || aAlwaysProxy) {
+    NS_GetMainThread(getter_AddRefs(mainThread));
+  }
+
+  return NS_ProxyRelease(mainThread, aDoomed, aAlwaysProxy);
+}
+
+/**
  * Class to safely handle main-thread-only pointers off the main thread.
  *
  * Classes like XPCWrappedJS are main-thread-only, which means that it is
  * forbidden to call methods on instances of these classes off the main thread.
  * For various reasons (see bug 771074), this restriction recently began to
  * apply to AddRef/Release as well.
  *
  * This presents a problem for consumers that wish to hold a callback alive