Bug 835283: Thread asserts for nr_socket_prsock r=jesup
authorEKR <ekr@rtfm.com>
Fri, 15 Feb 2013 18:33:31 -0800
changeset 122256 8febb0aa205f439e0449e4e9d6b17ff2bee005e0
parent 122255 adf96501de917cf1516beaa2ef79c19ae3a4c67a
child 122257 f992507bf21879a9b34f3e5568ed20108d038c2c
push id23196
push userrjesup@wgate.com
push dateMon, 18 Feb 2013 21:28:48 +0000
treeherdermozilla-inbound@8febb0aa205f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjesup
bugs835283
milestone21.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 835283: Thread asserts for nr_socket_prsock r=jesup
media/mtransport/nr_socket_prsock.cpp
media/mtransport/nr_socket_prsock.h
media/mtransport/test/ice_unittest.cpp
media/mtransport/test/transport_unittests.cpp
--- a/media/mtransport/nr_socket_prsock.cpp
+++ b/media/mtransport/nr_socket_prsock.cpp
@@ -97,16 +97,17 @@ nrappkit copyright:
 
 #include "nsCOMPtr.h"
 #include "nsASocketHandler.h"
 #include "nsISocketTransportService.h"
 #include "nsNetCID.h"
 #include "nsISupportsImpl.h"
 #include "nsServiceManagerUtils.h"
 #include "nsXPCOM.h"
+#include "runnable_utils.h"
 
 extern "C" {
 #include "nr_api.h"
 #include "async_wait.h"
 #include "nr_socket.h"
 #include "nr_socket_local.h"
 }
 
@@ -326,31 +327,37 @@ int NrSocket::create(nr_transport_addr *
   option.option = PR_SockOpt_Nonblocking;
   option.value.non_blocking = PR_TRUE;
   status = PR_SetSocketOption(fd_, &option);
   if (status != PR_SUCCESS) {
     r_log(LOG_GENERIC, LOG_CRIT, "Couldn't make socket nonblocking");
     ABORT(R_INTERNAL);
   }
 
+  // Remember our thread.
+  ststhread_ = do_QueryInterface(stservice, &rv);
+  if (!NS_SUCCEEDED(rv))
+    ABORT(R_INTERNAL);
+
   // Finally, register with the STS
   rv = stservice->AttachSocket(fd_, this);
   if (!NS_SUCCEEDED(rv)) {
     ABORT(R_INTERNAL);
   }
 
   _status = 0;
 
 abort:
   return(_status);
 }
 
 // This should be called on the STS thread.
 int NrSocket::sendto(const void *msg, size_t len,
                      int flags, nr_transport_addr *to) {
+  ASSERT_ON_THREAD(ststhread_);
   int r,_status;
   PRNetAddr naddr;
   int32_t status;
 
   if ((r=nr_transport_addr_to_praddr(to, &naddr)))
     ABORT(r);
 
   if(fd_==nullptr)
@@ -367,16 +374,17 @@ int NrSocket::sendto(const void *msg, si
   _status=0;
 abort:
   return(_status);
 }
 
 int NrSocket::recvfrom(void * buf, size_t maxlen,
                                        size_t *len, int flags,
                                        nr_transport_addr *from) {
+  ASSERT_ON_THREAD(ststhread_);
   int r,_status;
   PRNetAddr nfrom;
   int32_t status;
 
   status = PR_RecvFrom(fd_, buf, maxlen, flags, &nfrom, PR_INTERVAL_NO_WAIT);
   if (status <= 0) {
     r_log_e(LOG_GENERIC,LOG_ERR,"Error in recvfrom");
     ABORT(R_IO_ERROR);
@@ -389,21 +397,23 @@ int NrSocket::recvfrom(void * buf, size_
   //r_log(LOG_GENERIC,LOG_DEBUG,"Read %d bytes from %s",*len,addr->as_string);
 
   _status=0;
 abort:
   return(_status);
 }
 
 int NrSocket::getaddr(nr_transport_addr *addrp) {
+  ASSERT_ON_THREAD(ststhread_);
   return nr_transport_addr_copy(addrp, &my_addr_);
 }
 
 // Close the socket so that the STS will detach and then kill it
 void NrSocket::close() {
+  ASSERT_ON_THREAD(ststhread_);
   mCondition = NS_BASE_STREAM_CLOSED;
 }
 }  // close namespace
 
 
 using namespace mozilla;
 
 // Bridge to the nr_socket interface
--- a/media/mtransport/nr_socket_prsock.h
+++ b/media/mtransport/nr_socket_prsock.h
@@ -50,16 +50,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
 #include "nspr.h"
 #include "prio.h"
 
 #include "nsCOMPtr.h"
 #include "nsASocketHandler.h"
 #include "nsISocketTransportService.h"
 #include "nsXPCOM.h"
+#include "nsIEventTarget.h"
 
 #include "m_cpp_utils.h"
 
 namespace mozilla {
 
 class NrSocket : public nsASocketHandler {
 public:
   NrSocket() : fd_(nullptr) {
@@ -101,16 +102,16 @@ private:
   DISALLOW_COPY_ASSIGN(NrSocket);
 
   void fire_callback(int how);
 
   PRFileDesc *fd_;
   nr_transport_addr my_addr_;
   NR_async_cb cbs_[NR_ASYNC_WAIT_WRITE + 1];
   void *cb_args_[NR_ASYNC_WAIT_WRITE + 1];
-  nsCOMPtr<nsISocketTransportService> stservice_;
+  nsCOMPtr<nsIEventTarget> ststhread_;
 };
 
 int nr_praddr_to_transport_addr(const PRNetAddr *praddr,
                                 nr_transport_addr *addr, int keep);
 
 }  // close namespace
 #endif
--- a/media/mtransport/test/ice_unittest.cpp
+++ b/media/mtransport/test/ice_unittest.cpp
@@ -54,16 +54,22 @@ class IceTestPeer : public sigslot::has_
       received_(0),
       sent_(0),
       remote_(nullptr) {
     ice_ctx_->SignalGatheringCompleted.connect(this,
                                               &IceTestPeer::GatheringComplete);
     ice_ctx_->SignalCompleted.connect(this, &IceTestPeer::IceCompleted);
   }
 
+  ~IceTestPeer() {
+    test_utils->sts_target()->Dispatch(WrapRunnable(this,
+                                                    &IceTestPeer::Shutdown),
+        NS_DISPATCH_SYNC);
+  }
+
   void AddStream(int components) {
     char name[100];
     snprintf(name, sizeof(name), "%s:stream%d", name_.c_str(), (int)streams_.size());
 
     mozilla::RefPtr<NrIceMediaStream> stream =
         ice_ctx_->CreateStream(static_cast<char *>(name), components);
 
     ASSERT_TRUE(stream);
@@ -168,17 +174,23 @@ class IceTestPeer : public sigslot::has_
                         candidates[j],
                         &res), NS_DISPATCH_SYNC);
 
       ASSERT_TRUE(NS_SUCCEEDED(res));
     }
   }
 
   void Close() {
-    ice_ctx_->destroy_peer_ctx();
+    test_utils->sts_target()->Dispatch(
+      WrapRunnable(ice_ctx_, &NrIceCtx::destroy_peer_ctx),
+      NS_DISPATCH_SYNC);
+  }
+
+  void Shutdown() {
+    ice_ctx_ = nullptr;
   }
 
   void StartChecks() {
     nsresult res;
 
     // Now start checks
     test_utils->sts_target()->Dispatch(
         WrapRunnableRet(ice_ctx_, &NrIceCtx::StartChecks, &res),
@@ -308,17 +320,21 @@ class IceTest : public ::testing::Test {
     p2_->StartChecks();
 
     // Wait to see if we crash
     PR_Sleep(PR_MillisecondsToInterval(5000));
   }
 
   void SendReceive() {
     //    p1_->Send(2);
-    p1_->SendPacket(0, 1, reinterpret_cast<const unsigned char *>("TEST"), 4);
+    test_utils->sts_target()->Dispatch(
+        WrapRunnable(p1_.get(),
+                     &IceTestPeer::SendPacket, 0, 1,
+                     reinterpret_cast<const unsigned char *>("TEST"), 4),
+        NS_DISPATCH_SYNC);
     ASSERT_EQ(1u, p1_->sent());
     ASSERT_TRUE_WAIT(p2_->received() == 1, 1000);
   }
 
  protected:
   bool initted_;
   nsCOMPtr<nsIEventTarget> target_;
   mozilla::ScopedDeletePtr<IceTestPeer> p1_;
--- a/media/mtransport/test/transport_unittests.cpp
+++ b/media/mtransport/test/transport_unittests.cpp
@@ -135,16 +135,17 @@ class TransportTestPeer : public sigslot
     test_utils->sts_target()->Dispatch(
       WrapRunnable(this, &TransportTestPeer::DestroyFlow),
       NS_DISPATCH_SYNC);
   }
 
   void DestroyFlow() {
     loopback_->Disconnect();
     flow_ = nullptr;
+    ice_ctx_ = nullptr;
   }
 
   void SetDtlsAllowAll() {
     nsresult res = dtls_->SetVerificationAllowAll();
     ASSERT_TRUE(NS_SUCCEEDED(res));
   }
   void SetDtlsPeer(TransportTestPeer *peer, int digests, unsigned int damage) {
     unsigned int mask = 1;