Copied from upstream: https://hg.mozilla.org/releases/mozilla-esr38/raw-rev/221de852fda3 # HG changeset patch # User Randell Jesup # Date 1455862087 18000 # Node ID 221de852fda32714a9e484774ceafafb450ea73c # Parent b03db72e32f6e3acdc9f8705371cb222d7e6c456 Bug 1240760: Update DataChannel::Close() r=mcmanus, a=ritu MozReview-Commit-ID: 7nN9h3M3O8w diff --git a/netwerk/sctp/datachannel/DataChannel.cpp b/netwerk/sctp/datachannel/DataChannel.cpp --- a/netwerk/sctp/datachannel/DataChannel.cpp +++ b/netwerk/sctp/datachannel/DataChannel.cpp @@ -1771,17 +1771,17 @@ DataChannelConnection::HandleStreamReset } NS_DispatchToMainThread(new DataChannelOnMessageAvailable( DataChannelOnMessageAvailable::ON_CHANNEL_CLOSED, this, channel)); mStreams[channel->mStream] = nullptr; LOG(("Disconnected DataChannel %p from connection %p", (void *) channel.get(), (void *) channel->mConnection.get())); - channel->Destroy(); + channel->DestroyLocked(); // At this point when we leave here, the object is a zombie held alive only by the DOM object } else { LOG(("Can't find incoming channel %d",i)); } } } } @@ -2498,17 +2498,17 @@ DataChannelConnection::CloseInt(DataChan mStreams[channel->mStream] = nullptr; } else { SendOutgoingStreamReset(); } } aChannel->mState = CLOSING; if (mState == CLOSED) { // we're not going to hang around waiting - channel->Destroy(); + channel->DestroyLocked(); } // At this point when we leave here, the object is a zombie held alive only by the DOM object } void DataChannelConnection::CloseAll() { LOG(("Closing all channels (connection %p)", (void*) this)); // Don't need to lock here @@ -2552,23 +2552,25 @@ DataChannel::~DataChannel() // wrong, nothing bad happens. A worst it's a leak. NS_ASSERTION(mState == CLOSED || mState == CLOSING, "unexpected state in ~DataChannel"); } void DataChannel::Close() { ENSURE_DATACONNECTION; + RefPtr connection(mConnection); mConnection->Close(this); } // Used when disconnecting from the DataChannelConnection void -DataChannel::Destroy() +DataChannel::DestroyLocked() { + mConnection->mLock.AssertCurrentThreadOwns(); ENSURE_DATACONNECTION; LOG(("Destroying Data channel %u", mStream)); MOZ_ASSERT_IF(mStream != INVALID_STREAM, !mConnection->FindChannelByStream(mStream)); mStream = INVALID_STREAM; mState = CLOSED; mConnection = nullptr; diff --git a/netwerk/sctp/datachannel/DataChannel.h b/netwerk/sctp/datachannel/DataChannel.h --- a/netwerk/sctp/datachannel/DataChannel.h +++ b/netwerk/sctp/datachannel/DataChannel.h @@ -331,19 +331,20 @@ public: { NS_ASSERTION(mConnection,"NULL connection"); } private: ~DataChannel(); public: - void Destroy(); // when we disconnect from the connection after stream RESET + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DataChannel) - NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DataChannel) + // when we disconnect from the connection after stream RESET + void DestroyLocked(); // Close this DataChannel. Can be called multiple times. MUST be called // before destroying the DataChannel (state must be CLOSED or CLOSING). void Close(); // Set the listener (especially for channels created from the other side) void SetListener(DataChannelListener *aListener, nsISupports *aContext);