1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
Copied from upstream:
https://hg.mozilla.org/releases/mozilla-esr38/raw-rev/221de852fda3
# HG changeset patch
# User Randell Jesup <rjesup@jesup.org>
# 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<DataChannelConnection> 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);
|