| Index: third_party/WebKit/Source/modules/mediastream/RTCDataChannel.cpp
|
| diff --git a/third_party/WebKit/Source/modules/mediastream/RTCDataChannel.cpp b/third_party/WebKit/Source/modules/mediastream/RTCDataChannel.cpp
|
| index ad474ad7430119692b6e050980a21891d8132821..1114ae62c28dee6d702e387969072b78c517d335 100644
|
| --- a/third_party/WebKit/Source/modules/mediastream/RTCDataChannel.cpp
|
| +++ b/third_party/WebKit/Source/modules/mediastream/RTCDataChannel.cpp
|
| @@ -51,28 +51,30 @@
|
| exceptionState.throwDOMException(NotSupportedError, "Blob support not implemented yet");
|
| }
|
|
|
| -RTCDataChannel* RTCDataChannel::create(ExecutionContext* context, PassOwnPtr<WebRTCDataChannelHandler> handler)
|
| +RTCDataChannel* RTCDataChannel::create(ExecutionContext* context, RTCPeerConnection* connection, PassOwnPtr<WebRTCDataChannelHandler> handler)
|
| {
|
| ASSERT(handler);
|
| - return new RTCDataChannel(context, handler);
|
| -}
|
| -
|
| -RTCDataChannel* RTCDataChannel::create(ExecutionContext* context, WebRTCPeerConnectionHandler* peerConnectionHandler, const String& label, const WebRTCDataChannelInit& init, ExceptionState& exceptionState)
|
| + return new RTCDataChannel(context, connection, handler);
|
| +}
|
| +
|
| +RTCDataChannel* RTCDataChannel::create(ExecutionContext* context, RTCPeerConnection* connection, WebRTCPeerConnectionHandler* peerConnectionHandler, const String& label, const WebRTCDataChannelInit& init, ExceptionState& exceptionState)
|
| {
|
| OwnPtr<WebRTCDataChannelHandler> handler = adoptPtr(peerConnectionHandler->createDataChannel(label, init));
|
| if (!handler) {
|
| exceptionState.throwDOMException(NotSupportedError, "RTCDataChannel is not supported");
|
| return nullptr;
|
| }
|
| - return new RTCDataChannel(context, handler.release());
|
| -}
|
| -
|
| -RTCDataChannel::RTCDataChannel(ExecutionContext* context, PassOwnPtr<WebRTCDataChannelHandler> handler)
|
| + return new RTCDataChannel(context, connection, handler.release());
|
| +}
|
| +
|
| +RTCDataChannel::RTCDataChannel(ExecutionContext* context, RTCPeerConnection* connection, PassOwnPtr<WebRTCDataChannelHandler> handler)
|
| : m_executionContext(context)
|
| , m_handler(handler)
|
| + , m_stopped(false)
|
| , m_readyState(ReadyStateConnecting)
|
| , m_binaryType(BinaryTypeArrayBuffer)
|
| , m_scheduledEventTimer(this, &RTCDataChannel::scheduledEventTimerFired)
|
| + , m_connection(connection)
|
| , m_bufferedAmountLowThreshold(0U)
|
| {
|
| m_handler->setClient(this);
|
| @@ -80,8 +82,11 @@
|
|
|
| RTCDataChannel::~RTCDataChannel()
|
| {
|
| - // Notify the client that the channel is gone.
|
| - m_handler->setClient(0);
|
| + // If the peer connection and the data channel die in the same
|
| + // GC cycle stop has not been called and we need to notify the
|
| + // client that the channel is gone.
|
| + if (!m_stopped)
|
| + m_handler->setClient(0);
|
| }
|
|
|
| RTCDataChannel::ReadyState RTCDataChannel::getHandlerState() const
|
| @@ -230,12 +235,15 @@
|
|
|
| void RTCDataChannel::close()
|
| {
|
| + if (m_stopped)
|
| + return;
|
| +
|
| m_handler->close();
|
| }
|
|
|
| void RTCDataChannel::didChangeReadyState(WebRTCDataChannelHandlerClient::ReadyState newState)
|
| {
|
| - if (m_readyState == ReadyStateClosed)
|
| + if (m_stopped || m_readyState == ReadyStateClosed)
|
| return;
|
|
|
| m_readyState = newState;
|
| @@ -262,11 +270,17 @@
|
|
|
| void RTCDataChannel::didReceiveStringData(const WebString& text)
|
| {
|
| + if (m_stopped)
|
| + return;
|
| +
|
| scheduleDispatchEvent(MessageEvent::create(text));
|
| }
|
|
|
| void RTCDataChannel::didReceiveRawData(const char* data, size_t dataLength)
|
| {
|
| + if (m_stopped)
|
| + return;
|
| +
|
| if (m_binaryType == BinaryTypeBlob) {
|
| // FIXME: Implement.
|
| return;
|
| @@ -281,6 +295,9 @@
|
|
|
| void RTCDataChannel::didDetectError()
|
| {
|
| + if (m_stopped)
|
| + return;
|
| +
|
| scheduleDispatchEvent(Event::create(EventTypeNames::error));
|
| }
|
|
|
| @@ -292,6 +309,14 @@
|
| ExecutionContext* RTCDataChannel::executionContext() const
|
| {
|
| return m_executionContext;
|
| +}
|
| +
|
| +void RTCDataChannel::stop()
|
| +{
|
| + m_stopped = true;
|
| + m_readyState = ReadyStateClosed;
|
| + m_handler->setClient(0);
|
| + m_executionContext = 0;
|
| }
|
|
|
| void RTCDataChannel::scheduleDispatchEvent(PassRefPtrWillBeRawPtr<Event> event)
|
| @@ -304,6 +329,9 @@
|
|
|
| void RTCDataChannel::scheduledEventTimerFired(Timer<RTCDataChannel>*)
|
| {
|
| + if (m_stopped)
|
| + return;
|
| +
|
| WillBeHeapVector<RefPtrWillBeMember<Event>> events;
|
| events.swap(m_scheduledEvents);
|
|
|
| @@ -314,10 +342,19 @@
|
| events.clear();
|
| }
|
|
|
| +void RTCDataChannel::clearWeakMembers(Visitor* visitor)
|
| +{
|
| + if (Heap::isHeapObjectAlive(m_connection))
|
| + return;
|
| + stop();
|
| + m_connection = nullptr;
|
| +}
|
| +
|
| DEFINE_TRACE(RTCDataChannel)
|
| {
|
| visitor->trace(m_executionContext);
|
| visitor->trace(m_scheduledEvents);
|
| + visitor->template registerWeakMembers<RTCDataChannel, &RTCDataChannel::clearWeakMembers>(this);
|
| RefCountedGarbageCollectedEventTargetWithInlineData<RTCDataChannel>::trace(visitor);
|
| }
|
|
|
|
|