Bug 1341374: ensure mtransport refcounting is happening on the same thread draft
authorNils Ohlmeier [:drno] <drno@ohlmeier.org>
Thu, 23 Feb 2017 21:57:50 -0800
changeset 490294 8f84eae94583c765b6e075aa3570c160b32971de
parent 490265 5d1ebf7782dfd48afbac00e99f93c1726affec09
child 547220 a6e8b2e7261ba4311b051aba48a14c9db08da627
push id47056
push userdrno@ohlmeier.org
push dateTue, 28 Feb 2017 02:28:58 +0000
bugs1341374
milestone54.0a1
Bug 1341374: ensure mtransport refcounting is happening on the same thread MozReview-Commit-ID: 6Q3Wc1dIfnR
media/mtransport/nr_socket_prsock.cpp
media/mtransport/nr_socket_prsock.h
--- a/media/mtransport/nr_socket_prsock.cpp
+++ b/media/mtransport/nr_socket_prsock.cpp
@@ -202,49 +202,62 @@ public:
   nsIThread* GetThread() {
     return mThread;
   }
 
   /*
    * Keep track of how many instances are using a SingletonThreadHolder.
    * When no one is using it, shut it down
    */
-  MozExternalRefCountType AddUse()
+  void AddUse()
   {
-    MOZ_ASSERT(mParentThread == NS_GetCurrentThread());
+    RUN_ON_THREAD(mParentThread,
+                  mozilla::WrapRunnable(RefPtr<SingletonThreadHolder>(this),
+                                        &SingletonThreadHolder::AddUse_i),
+                  NS_DISPATCH_SYNC);
+  }
+
+  void AddUse_i()
+  {
     MOZ_ASSERT(int32_t(mUseCount) >= 0, "illegal refcnt");
     nsrefcnt count = ++mUseCount;
     if (count == 1) {
       // idle -> in-use
       nsresult rv = NS_NewNamedThread(mName, getter_AddRefs(mThread));
       MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv) && mThread,
                          "Should successfully create mtransport I/O thread");
       r_log(LOG_GENERIC,LOG_DEBUG,"Created wrapped SingletonThread %p",
             mThread.get());
     }
-    r_log(LOG_GENERIC,LOG_DEBUG,"AddUse: %lu", (unsigned long) count);
-    return count;
+    r_log(LOG_GENERIC,LOG_DEBUG,"AddUse_i: %lu", (unsigned long) count);
   }
 
-  MozExternalRefCountType ReleaseUse()
+  void ReleaseUse()
+  {
+    RUN_ON_THREAD(mParentThread,
+                  mozilla::WrapRunnable(RefPtr<SingletonThreadHolder>(this),
+                                        &SingletonThreadHolder::ReleaseUse_i),
+                  NS_DISPATCH_SYNC);
+  }
+
+  void ReleaseUse_i()
   {
     MOZ_ASSERT(mParentThread == NS_GetCurrentThread());
     nsrefcnt count = --mUseCount;
     MOZ_ASSERT(int32_t(mUseCount) >= 0, "illegal refcnt");
     if (count == 0) {
       // in-use -> idle -- no one forcing it to remain instantiated
       r_log(LOG_GENERIC,LOG_DEBUG,"Shutting down wrapped SingletonThread %p",
             mThread.get());
       mThread->Shutdown();
       mThread = nullptr;
       // It'd be nice to use a timer instead...  But be careful of
       // xpcom-shutdown-threads in that case
     }
-    r_log(LOG_GENERIC,LOG_DEBUG,"ReleaseUse: %lu", (unsigned long) count);
-    return count;
+    r_log(LOG_GENERIC,LOG_DEBUG,"ReleaseUse_i: %lu", (unsigned long) count);
   }
 
 private:
   nsCString mName;
   nsAutoRefCnt mUseCount;
   nsCOMPtr<nsIThread> mParentThread;
   nsCOMPtr<nsIThread> mThread;
 };
@@ -1683,18 +1696,17 @@ NrTcpSocketIpc::NrTcpSocketIpc(nsIThread
 
 NrTcpSocketIpc::~NrTcpSocketIpc()
 {
   // also guarantees socket_child_ is released from the io_thread
 
   // close(), but transfer the socket_child_ reference to die as well
   RUN_ON_THREAD(io_thread_,
                 mozilla::WrapRunnableNM(&NrTcpSocketIpc::release_child_i,
-                                        socket_child_.forget().take(),
-                                        sts_thread_),
+                                        socket_child_.forget().take()),
                 NS_DISPATCH_NORMAL);
 }
 
 //
 // nsITCPSocketCallback methods
 //
 NS_IMETHODIMP NrTcpSocketIpc::UpdateReadyState(uint32_t aReadyState) {
   NrSocketIpcState temp = NR_INIT;
@@ -1996,18 +2008,17 @@ void NrTcpSocketIpc::close_i() {
   if (!socket_child_) {
     return;
   }
   socket_child_->SendClose();
 }
 
 // close(), but transfer the socket_child_ reference to die as well
 // static
-void NrTcpSocketIpc::release_child_i(dom::TCPSocketChild* aChild,
-                                     nsCOMPtr<nsIEventTarget> sts_thread) {
+void NrTcpSocketIpc::release_child_i(dom::TCPSocketChild* aChild) {
   RefPtr<dom::TCPSocketChild> socket_child_ref =
     already_AddRefed<dom::TCPSocketChild>(aChild);
   if (socket_child_ref) {
     socket_child_ref->SendClose();
   }
   // io_thread_ is MainThread, so no use to release
 }
 
--- a/media/mtransport/nr_socket_prsock.h
+++ b/media/mtransport/nr_socket_prsock.h
@@ -369,17 +369,17 @@ private:
                  uint16_t remote_port,
                  const nsACString &local_addr,
                  uint16_t local_port,
                  const nsACString &tls_host);
   void write_i(nsAutoPtr<InfallibleTArray<uint8_t>> buf,
                uint32_t tracking_number);
   void close_i();
 
-  static void release_child_i(dom::TCPSocketChild* aChild, nsCOMPtr<nsIEventTarget> ststhread);
+  static void release_child_i(dom::TCPSocketChild* aChild);
 
   // STS thread executor
   void message_sent_s(uint32_t bufferedAmount, uint32_t tracking_number);
   void recv_message_s(nr_tcp_message *msg);
   void update_state_s(NrSocketIpcState next_state);
   void maybe_post_socket_ready();
 
   // Accessed from UpdateReadyState (not sts_thread) to avoid sending