Bug 827878 - TransportFlows must be released on STS thread. r=ekr, a=akeybl
authorRandell Jesup <rjesup@jesup.org>
Sat, 12 Jan 2013 05:40:22 -0500
changeset 127192 d39c44ce7f8b6aec65bc1f70a9a244800bd9de55
parent 127191 c5fa1c30a15a519727d03c23c1cc3133ec004d3e
child 127193 003d8353090e31fef67381d7c4e330975c0ffcef
push id2151
push userlsblakk@mozilla.com
push dateTue, 19 Feb 2013 18:06:57 +0000
treeherdermozilla-beta@4952e88741ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersekr, akeybl
bugs827878
milestone20.0a2
Bug 827878 - TransportFlows must be released on STS thread. r=ekr, a=akeybl
netwerk/sctp/datachannel/DataChannel.cpp
netwerk/sctp/datachannel/DataChannel.h
--- a/netwerk/sctp/datachannel/DataChannel.cpp
+++ b/netwerk/sctp/datachannel/DataChannel.cpp
@@ -154,17 +154,24 @@ DataChannelConnection::DataChannelConnec
 
 DataChannelConnection::~DataChannelConnection()
 {
   LOG(("Deleting DataChannelConnection %p", (void *) this));
   // This may die on the MainThread, or on the STS thread
   MOZ_ASSERT(mState == CLOSED);
   MOZ_ASSERT(!mMasterSocket);
   MOZ_ASSERT(mPending.GetSize() == 0);
+
   // Already disconnected from sigslot/mTransportFlow
+  // TransportFlows must be released from the STS thread
+  if (mTransportFlow && !IsSTSThread()) {
+    MOZ_ASSERT(mSTS);
+    RUN_ON_THREAD(mSTS, WrapRunnableNM(ReleaseTransportFlow, mTransportFlow),
+                  NS_DISPATCH_NORMAL);
+  }
 }
 
 void
 DataChannelConnection::Destroy()
 {
   // Though it's probably ok to do this and close the sockets;
   // if we really want it to do true clean shutdowns it can
   // create a dependant Internal object that would remain around
@@ -821,16 +828,19 @@ DataChannelConnection::SendOpenRequestMe
 }
 
 // XXX This should use a separate thread (outbound queue) which should
 // select() to know when to *try* to send data to the socket again.
 // Alternatively, it can use a timeout, but that's guaranteed to be wrong
 // (just not sure in what direction).  We could re-implement NSPR's
 // PR_POLL_WRITE/etc handling... with a lot of work.
 
+// Better yet, use the SCTP stack's notifications on buffer state to avoid
+// filling the SCTP's buffers.
+
 // returns if we're still blocked or not
 bool
 DataChannelConnection::SendDeferredMessages()
 {
   uint32_t i;
   nsRefPtr<DataChannel> channel; // we may null out the refs to this
   bool still_blocked = false;
   bool sent = false;
--- a/netwerk/sctp/datachannel/DataChannel.h
+++ b/netwerk/sctp/datachannel/DataChannel.h
@@ -228,16 +228,20 @@ private:
     bool on = false;
     if (mSTS) {
       mSTS->IsOnCurrentThread(&on);
     }
     return on;
   }
 #endif
 
+  // Exists solely for proxying release of the TransportFlow to the STS thread
+  static void ReleaseTransportFlow(nsRefPtr<TransportFlow> aFlow) {}
+
+  // Data:
   // NOTE: while these arrays will auto-expand, increases in the number of
   // channels available from the stack must be negotiated!
   nsAutoTArray<nsRefPtr<DataChannel>,16> mStreamsOut;
   nsAutoTArray<nsRefPtr<DataChannel>,16> mStreamsIn;
   nsDeque mPending; // Holds already_AddRefed<DataChannel>s -- careful!
 
   // Streams pending reset
   nsAutoTArray<uint16_t,4> mStreamsResetting;