Bug 805251 - Clean up DataChannel close logic r=mcmanus
authorRandell Jesup <rjesup@jesup.org>
Thu, 17 Jan 2013 05:26:40 -0500
changeset 119140 08f1385d7f0fa7bd0e74e24823a047a280ea0ab6
parent 119139 0b076541046058893743dbebe3a6336e0a2550e7
child 119141 15db83a182f50f40fe4333d6354e1015edb1d95d
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersmcmanus
bugs805251
milestone21.0a1
Bug 805251 - Clean up DataChannel close logic r=mcmanus
netwerk/sctp/datachannel/DataChannel.cpp
netwerk/sctp/datachannel/DataChannel.h
--- a/netwerk/sctp/datachannel/DataChannel.cpp
+++ b/netwerk/sctp/datachannel/DataChannel.cpp
@@ -905,17 +905,17 @@ DataChannelConnection::SendDeferredMessa
       if (SendOpenAckMessage(channel->mStreamOut)) {
         channel->mFlags &= ~DATA_CHANNEL_FLAGS_SEND_ACK;
         sent = true;
       } else {
         if (errno == EAGAIN || errno == EWOULDBLOCK) {
           still_blocked = true;
         } else {
           // Close the channel, inform the user
-          Close(channel->mStreamOut);
+          Close(channel);
         }
       }
     }
     if (still_blocked)
       break;
 
     if (channel->mFlags & DATA_CHANNEL_FLAGS_SEND_DATA) {
       bool failed_send = false;
@@ -1212,28 +1212,16 @@ DataChannelConnection::HandleDataMessage
     channel->SendOrQueue(new DataChannelOnMessageAvailable(
                            DataChannelOnMessageAvailable::ON_DATA, this,
                            channel, recvData, length));
   }
 }
 
 // Called with mLock locked!
 void
-DataChannel::SendOrQueue(DataChannelOnMessageAvailable *aMessage)
-{
-  if (!mReady &&
-      (mState == CONNECTING || mState == WAITING_TO_OPEN)) {
-    mQueuedMessages.AppendElement(aMessage);
-  } else {
-    NS_DispatchToMainThread(aMessage);
-  }
-}
-
-// Called with mLock locked!
-void
 DataChannelConnection::HandleMessage(const void *buffer, size_t length, uint32_t ppid, uint16_t streamIn)
 {
   const struct rtcweb_datachannel_open_request *req;
   const struct rtcweb_datachannel_open_response *rsp;
   const struct rtcweb_datachannel_ack *ack, *msg;
 
   mLock.AssertCurrentThreadOwns();
 
@@ -2027,37 +2015,34 @@ DataChannelConnection::SendMsgCommon(uin
   NS_ENSURE_TRUE(channel, 0);
 
   if (isBinary)
     return SendBinary(channel, data, len);
   return SendMsgInternal(channel, data, len, DATA_CHANNEL_PPID_DOMSTRING);
 }
 
 void
-DataChannelConnection::Close(uint16_t streamOut)
+DataChannelConnection::Close(DataChannel *aChannel)
 {
-  nsRefPtr<DataChannel> channel; // make sure it doesn't go away on us
+  MOZ_ASSERT(aChannel);
+  nsRefPtr<DataChannel> channel(aChannel); // make sure it doesn't go away on us
 
   MutexAutoLock lock(mLock);
-  channel = FindChannelByStreamOut(streamOut);
-  if (channel) {
-    LOG(("Connection %p/Channel %p: Closing stream %d",
-         (void *) channel->mConnection.get(), (void *) channel.get(), streamOut));
-    if (channel->mState == CLOSED || channel->mState == CLOSING) {
-      LOG(("Channel already closing/closed (%d)", channel->mState));
-      return;
-    }
-    channel->mBufferedData.Clear();
-    if (channel->mStreamOut != INVALID_STREAM)
-      ResetOutgoingStream(channel->mStreamOut);
+  LOG(("Connection %p/Channel %p: Closing stream %d",
+       channel->mConnection.get(), channel.get(), channel->mStreamOut));
+  if (channel->mState == CLOSED || channel->mState == CLOSING) {
+    LOG(("Channel already closing/closed (%d)", channel->mState));
+    return;
+  }
+  channel->mBufferedData.Clear();
+  if (channel->mStreamOut != INVALID_STREAM) {
+    ResetOutgoingStream(channel->mStreamOut);
     SendOutgoingStreamReset();
-    channel->mState = CLOSING;
-  } else {
-    LOG(("!!!? no channel when closing stream %d?",streamOut));
   }
+  channel->mState = CLOSING;
 }
 
 void DataChannelConnection::CloseAll()
 {
   LOG(("Closing all channels"));
   // Don't need to lock here
 
   // Make sure no more channels will be opened
@@ -2077,18 +2062,24 @@ void DataChannelConnection::CloseAll()
   while (nullptr != (channel = dont_AddRef(static_cast<DataChannel *>(mPending.PopFront())))) {
     LOG(("closing pending channel %p, stream %d", channel.get(), channel->mStreamOut));
     channel->Close(); // also releases the ref on each iteration
   }
 }
 
 DataChannel::~DataChannel()
 {
-  if (mConnection)
-    Close();
+  Close();
+}
+
+void
+DataChannel::Close()
+{
+  ENSURE_DATACONNECTION;
+  mConnection->Close(this);
 }
 
 // Used when disconnecting from the DataChannelConnection
 void
 DataChannel::Destroy()
 {
   ENSURE_DATACONNECTION;
 
@@ -2099,28 +2090,16 @@ DataChannel::Destroy()
                 !mConnection->FindChannelByStreamIn(mStreamIn));
   mStreamIn  = INVALID_STREAM;
   mStreamOut = INVALID_STREAM;
   mState = CLOSED;
   mConnection = nullptr;
 }
 
 void
-DataChannel::Close()
-{
-  if (mState == CLOSING || mState == CLOSED ||
-      mStreamOut == INVALID_STREAM) {
-    return;
-  }
-  mState = CLOSING;
-  ENSURE_DATACONNECTION;
-  mConnection->Close(mStreamOut);
-}
-
-void
 DataChannel::SetListener(DataChannelListener *aListener, nsISupports *aContext)
 {
   MOZ_ASSERT(!mListener); // only should be set once, avoids races w/o locking
   mContext = aContext;
   mListener = aListener;
 }
 
 // May be called from another (i.e. Main) thread!
@@ -2156,9 +2135,21 @@ DataChannel::GetBufferedAmount()
 {
   uint32_t buffered = 0;
   for (uint32_t i = 0; i < mBufferedData.Length(); ++i) {
     buffered += mBufferedData[i]->mLength;
   }
   return buffered;
 }
 
+// Called with mLock locked!
+void
+DataChannel::SendOrQueue(DataChannelOnMessageAvailable *aMessage)
+{
+  if (!mReady &&
+      (mState == CONNECTING || mState == WAITING_TO_OPEN)) {
+    mQueuedMessages.AppendElement(aMessage);
+  } else {
+    NS_DispatchToMainThread(aMessage);
+  }
+}
+
 } // namespace mozilla
--- a/netwerk/sctp/datachannel/DataChannel.h
+++ b/netwerk/sctp/datachannel/DataChannel.h
@@ -133,17 +133,17 @@ public:
   } Type;
 
   already_AddRefed<DataChannel> Open(const nsACString& label,
                                      Type type, bool inOrder,
                                      uint32_t prValue,
                                      DataChannelListener *aListener,
                                      nsISupports *aContext);
 
-  void Close(uint16_t stream);
+  void Close(DataChannel *aChannel);
   void CloseAll();
 
   int32_t SendMsg(uint16_t stream, const nsACString &aMsg)
     {
       return SendMsgCommon(stream, aMsg, false);
     }
   int32_t SendBinaryMsg(uint16_t stream, const nsACString &aMsg)
     {