Commit f2d6a003 authored by sergeyu@chromium.org's avatar sergeyu@chromium.org

Add CancelChannelCreation() in protocol::Session interface.

The new method cancels channel creation for pending channel. This 
prevents some potential crashes.


Review URL: http://codereview.chromium.org/8573013

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110401 0039d316-1c4b-4281-b951-d872f2087c98
parent 59886ede
...@@ -162,10 +162,9 @@ void ConnectionToClient::CloseOnError() { ...@@ -162,10 +162,9 @@ void ConnectionToClient::CloseOnError() {
} }
void ConnectionToClient::CloseChannels() { void ConnectionToClient::CloseChannels() {
if (video_writer_.get()) video_writer_.reset();
video_writer_->Close(); client_control_sender_.reset();
if (client_control_sender_.get()) dispatcher_.reset();
client_control_sender_->Close();
} }
} // namespace protocol } // namespace protocol
......
...@@ -242,6 +242,9 @@ void FakeSession::CreateDatagramChannel( ...@@ -242,6 +242,9 @@ void FakeSession::CreateDatagramChannel(
callback.Run(channel); callback.Run(channel);
} }
void FakeSession::CancelChannelCreation(const std::string& name) {
}
FakeSocket* FakeSession::control_channel() { FakeSocket* FakeSession::control_channel() {
return &control_channel_; return &control_channel_;
} }
......
...@@ -138,33 +138,36 @@ class FakeSession : public Session { ...@@ -138,33 +138,36 @@ class FakeSession : public Session {
FakeUdpSocket* GetDatagramChannel(const std::string& name); FakeUdpSocket* GetDatagramChannel(const std::string& name);
// Session interface. // Session interface.
virtual void SetStateChangeCallback(const StateChangeCallback& callback); virtual void SetStateChangeCallback(
const StateChangeCallback& callback) OVERRIDE;
virtual Session::Error error(); virtual Session::Error error() OVERRIDE;
virtual void CreateStreamChannel( virtual void CreateStreamChannel(
const std::string& name, const StreamChannelCallback& callback); const std::string& name, const StreamChannelCallback& callback) OVERRIDE;
virtual void CreateDatagramChannel( virtual void CreateDatagramChannel(
const std::string& name, const DatagramChannelCallback& callback); const std::string& name,
const DatagramChannelCallback& callback) OVERRIDE;
virtual void CancelChannelCreation(const std::string& name) OVERRIDE;
virtual FakeSocket* control_channel(); virtual FakeSocket* control_channel() OVERRIDE;
virtual FakeSocket* event_channel(); virtual FakeSocket* event_channel() OVERRIDE;
virtual const std::string& jid(); virtual const std::string& jid() OVERRIDE;
virtual const CandidateSessionConfig* candidate_config(); virtual const CandidateSessionConfig* candidate_config() OVERRIDE;
virtual const SessionConfig& config(); virtual const SessionConfig& config() OVERRIDE;
virtual void set_config(const SessionConfig& config); virtual void set_config(const SessionConfig& config) OVERRIDE;
virtual const std::string& initiator_token(); virtual const std::string& initiator_token() OVERRIDE;
virtual void set_initiator_token(const std::string& initiator_token); virtual void set_initiator_token(const std::string& initiator_token) OVERRIDE;
virtual const std::string& receiver_token(); virtual const std::string& receiver_token() OVERRIDE;
virtual void set_receiver_token(const std::string& receiver_token); virtual void set_receiver_token(const std::string& receiver_token) OVERRIDE;
virtual void set_shared_secret(const std::string& secret); virtual void set_shared_secret(const std::string& secret) OVERRIDE;
virtual const std::string& shared_secret(); virtual const std::string& shared_secret() OVERRIDE;
virtual void Close(); virtual void Close() OVERRIDE;
public: public:
StateChangeCallback callback_; StateChangeCallback callback_;
......
...@@ -172,6 +172,14 @@ void JingleSession::CreateDatagramChannel( ...@@ -172,6 +172,14 @@ void JingleSession::CreateDatagramChannel(
name, new JingleDatagramConnector(this, name, callback)); name, new JingleDatagramConnector(this, name, callback));
} }
void JingleSession::CancelChannelCreation(const std::string& name) {
ChannelConnectorsMap::iterator it = channel_connectors_.find(name);
if (it != channel_connectors_.end()) {
delete it->second;
channel_connectors_.erase(it);
}
}
net::Socket* JingleSession::control_channel() { net::Socket* JingleSession::control_channel() {
DCHECK(CalledOnValidThread()); DCHECK(CalledOnValidThread());
return control_channel_socket_.get(); return control_channel_socket_.get();
...@@ -432,7 +440,7 @@ void JingleSession::OnChannelConnectorFinished( ...@@ -432,7 +440,7 @@ void JingleSession::OnChannelConnectorFinished(
const std::string& name, JingleChannelConnector* connector) { const std::string& name, JingleChannelConnector* connector) {
DCHECK(CalledOnValidThread()); DCHECK(CalledOnValidThread());
DCHECK_EQ(channel_connectors_[name], connector); DCHECK_EQ(channel_connectors_[name], connector);
channel_connectors_[name] = NULL; channel_connectors_.erase(name);
} }
void JingleSession::CreateChannels() { void JingleSession::CreateChannels() {
......
...@@ -36,6 +36,7 @@ class JingleSession : public protocol::Session, ...@@ -36,6 +36,7 @@ class JingleSession : public protocol::Session,
virtual void CreateDatagramChannel( virtual void CreateDatagramChannel(
const std::string& name, const std::string& name,
const DatagramChannelCallback& callback) OVERRIDE; const DatagramChannelCallback& callback) OVERRIDE;
virtual void CancelChannelCreation(const std::string& name) OVERRIDE;
virtual net::Socket* control_channel() OVERRIDE; virtual net::Socket* control_channel() OVERRIDE;
virtual net::Socket* event_channel() OVERRIDE; virtual net::Socket* event_channel() OVERRIDE;
virtual const std::string& jid() OVERRIDE; virtual const std::string& jid() OVERRIDE;
...@@ -55,6 +56,8 @@ class JingleSession : public protocol::Session, ...@@ -55,6 +56,8 @@ class JingleSession : public protocol::Session,
friend class JingleSessionManager; friend class JingleSessionManager;
friend class JingleStreamConnector; friend class JingleStreamConnector;
typedef std::map<std::string, JingleChannelConnector*> ChannelConnectorsMap;
// Create a JingleSession used in client mode. A server certificate is // Create a JingleSession used in client mode. A server certificate is
// required. // required.
static JingleSession* CreateClientSession(JingleSessionManager* manager, static JingleSession* CreateClientSession(JingleSessionManager* manager,
...@@ -175,7 +178,7 @@ class JingleSession : public protocol::Session, ...@@ -175,7 +178,7 @@ class JingleSession : public protocol::Session,
scoped_ptr<const CandidateSessionConfig> candidate_config_; scoped_ptr<const CandidateSessionConfig> candidate_config_;
// Channels that are currently being connected. // Channels that are currently being connected.
std::map<std::string, JingleChannelConnector*> channel_connectors_; ChannelConnectorsMap channel_connectors_;
scoped_ptr<net::Socket> control_channel_socket_; scoped_ptr<net::Socket> control_channel_socket_;
scoped_ptr<net::Socket> event_channel_socket_; scoped_ptr<net::Socket> event_channel_socket_;
......
...@@ -38,7 +38,10 @@ class PepperChannel : public base::NonThreadSafe { ...@@ -38,7 +38,10 @@ class PepperChannel : public base::NonThreadSafe {
virtual void AddRemoveCandidate(const cricket::Candidate& candidate) = 0; virtual void AddRemoveCandidate(const cricket::Candidate& candidate) = 0;
// Name of the channel. // Name of the channel.
virtual const std::string& name() = 0; virtual const std::string& name() const = 0;
// returns true if the channel is already connected
virtual bool is_connected() const = 0;
protected: protected:
DISALLOW_COPY_AND_ASSIGN(PepperChannel); DISALLOW_COPY_AND_ASSIGN(PepperChannel);
......
...@@ -126,6 +126,14 @@ void PepperSession::CreateDatagramChannel( ...@@ -126,6 +126,14 @@ void PepperSession::CreateDatagramChannel(
NOTREACHED(); NOTREACHED();
} }
void PepperSession::CancelChannelCreation(const std::string& name) {
ChannelsMap::iterator it = channels_.find(name);
if (it != channels_.end() && !it->second->is_connected()) {
delete it->second;
DCHECK(!channels_[name]);
}
}
net::Socket* PepperSession::control_channel() { net::Socket* PepperSession::control_channel() {
DCHECK(CalledOnValidThread()); DCHECK(CalledOnValidThread());
return control_channel_socket_.get(); return control_channel_socket_.get();
......
...@@ -48,6 +48,7 @@ class PepperSession : public Session { ...@@ -48,6 +48,7 @@ class PepperSession : public Session {
virtual void CreateDatagramChannel( virtual void CreateDatagramChannel(
const std::string& name, const std::string& name,
const DatagramChannelCallback& callback) OVERRIDE; const DatagramChannelCallback& callback) OVERRIDE;
virtual void CancelChannelCreation(const std::string& name) OVERRIDE;
virtual net::Socket* control_channel() OVERRIDE; virtual net::Socket* control_channel() OVERRIDE;
virtual net::Socket* event_channel() OVERRIDE; virtual net::Socket* event_channel() OVERRIDE;
virtual const std::string& jid() OVERRIDE; virtual const std::string& jid() OVERRIDE;
......
...@@ -81,6 +81,7 @@ PepperStreamChannel::PepperStreamChannel( ...@@ -81,6 +81,7 @@ PepperStreamChannel::PepperStreamChannel(
} }
PepperStreamChannel::~PepperStreamChannel() { PepperStreamChannel::~PepperStreamChannel() {
session_->OnDeleteChannel(this);
// Verify that the |channel_| is ether destroyed or we own it. // Verify that the |channel_| is ether destroyed or we own it.
DCHECK_EQ(channel_, owned_channel_.get()); DCHECK_EQ(channel_, owned_channel_.get());
// Channel should be already destroyed if we were connected. // Channel should be already destroyed if we were connected.
...@@ -163,17 +164,21 @@ void PepperStreamChannel::AddRemoveCandidate( ...@@ -163,17 +164,21 @@ void PepperStreamChannel::AddRemoveCandidate(
channel_->AddRemoteCandidate(jingle_glue::SerializeP2PCandidate(candidate)); channel_->AddRemoteCandidate(jingle_glue::SerializeP2PCandidate(candidate));
} }
const std::string& PepperStreamChannel::name() { const std::string& PepperStreamChannel::name() const {
DCHECK(CalledOnValidThread()); DCHECK(CalledOnValidThread());
return name_; return name_;
} }
bool PepperStreamChannel::is_connected() const {
DCHECK(CalledOnValidThread());
return connected_;
}
void PepperStreamChannel::OnChannelDeleted() { void PepperStreamChannel::OnChannelDeleted() {
if (connected_) { if (connected_) {
channel_ = NULL; channel_ = NULL;
// The PepperTransportSocketAdapter is being deleted, so delete the // The PepperTransportSocketAdapter is being deleted, so delete
// channel too. // the channel too.
session_->OnDeleteChannel(this);
delete this; delete this;
} }
} }
......
...@@ -39,7 +39,8 @@ class PepperStreamChannel : public PepperChannel, ...@@ -39,7 +39,8 @@ class PepperStreamChannel : public PepperChannel,
const TransportConfig& transport_config, const TransportConfig& transport_config,
const std::string& remote_cert) OVERRIDE; const std::string& remote_cert) OVERRIDE;
virtual void AddRemoveCandidate(const cricket::Candidate& candidate) OVERRIDE; virtual void AddRemoveCandidate(const cricket::Candidate& candidate) OVERRIDE;
virtual const std::string& name() OVERRIDE; virtual const std::string& name() const OVERRIDE;
virtual bool is_connected() const OVERRIDE;
// PepperTransportSocketAdapter implementation. // PepperTransportSocketAdapter implementation.
virtual void OnChannelDeleted() OVERRIDE; virtual void OnChannelDeleted() OVERRIDE;
......
...@@ -15,19 +15,24 @@ namespace remoting { ...@@ -15,19 +15,24 @@ namespace remoting {
namespace protocol { namespace protocol {
ProtobufVideoReader::ProtobufVideoReader(VideoPacketFormat::Encoding encoding) ProtobufVideoReader::ProtobufVideoReader(VideoPacketFormat::Encoding encoding)
: encoding_(encoding), : session_(NULL),
encoding_(encoding),
video_stub_(NULL) { video_stub_(NULL) {
} }
ProtobufVideoReader::~ProtobufVideoReader() { } ProtobufVideoReader::~ProtobufVideoReader() {
if (session_)
session_->CancelChannelCreation(kVideoChannelName);
}
void ProtobufVideoReader::Init(protocol::Session* session, void ProtobufVideoReader::Init(protocol::Session* session,
VideoStub* video_stub, VideoStub* video_stub,
const InitializedCallback& callback) { const InitializedCallback& callback) {
session_ = session;
initialized_callback_ = callback; initialized_callback_ = callback;
video_stub_ = video_stub; video_stub_ = video_stub;
session->CreateStreamChannel( session_->CreateStreamChannel(
kVideoChannelName, kVideoChannelName,
base::Bind(&ProtobufVideoReader::OnChannelReady, base::Unretained(this))); base::Bind(&ProtobufVideoReader::OnChannelReady, base::Unretained(this)));
} }
......
...@@ -33,6 +33,8 @@ class ProtobufVideoReader : public VideoReader { ...@@ -33,6 +33,8 @@ class ProtobufVideoReader : public VideoReader {
void OnChannelReady(net::StreamSocket* socket); void OnChannelReady(net::StreamSocket* socket);
void OnNewData(VideoPacket* packet, const base::Closure& done_task); void OnNewData(VideoPacket* packet, const base::Closure& done_task);
Session* session_;
InitializedCallback initialized_callback_; InitializedCallback initialized_callback_;
VideoPacketFormat::Encoding encoding_; VideoPacketFormat::Encoding encoding_;
......
...@@ -17,16 +17,20 @@ namespace remoting { ...@@ -17,16 +17,20 @@ namespace remoting {
namespace protocol { namespace protocol {
ProtobufVideoWriter::ProtobufVideoWriter(base::MessageLoopProxy* message_loop) ProtobufVideoWriter::ProtobufVideoWriter(base::MessageLoopProxy* message_loop)
: buffered_writer_(new BufferedSocketWriter(message_loop)) { : session_(NULL),
buffered_writer_(new BufferedSocketWriter(message_loop)) {
} }
ProtobufVideoWriter::~ProtobufVideoWriter() { } ProtobufVideoWriter::~ProtobufVideoWriter() {
Close();
}
void ProtobufVideoWriter::Init(protocol::Session* session, void ProtobufVideoWriter::Init(protocol::Session* session,
const InitializedCallback& callback) { const InitializedCallback& callback) {
session_ = session;
initialized_callback_ = callback; initialized_callback_ = callback;
session->CreateStreamChannel( session_->CreateStreamChannel(
kVideoChannelName, kVideoChannelName,
base::Bind(&ProtobufVideoWriter::OnChannelReady, base::Unretained(this))); base::Bind(&ProtobufVideoWriter::OnChannelReady, base::Unretained(this)));
} }
...@@ -48,6 +52,10 @@ void ProtobufVideoWriter::OnChannelReady(net::StreamSocket* socket) { ...@@ -48,6 +52,10 @@ void ProtobufVideoWriter::OnChannelReady(net::StreamSocket* socket) {
void ProtobufVideoWriter::Close() { void ProtobufVideoWriter::Close() {
buffered_writer_->Close(); buffered_writer_->Close();
channel_.reset(); channel_.reset();
if (session_) {
session_->CancelChannelCreation(kVideoChannelName);
session_ = NULL;
}
} }
void ProtobufVideoWriter::ProcessVideoPacket(const VideoPacket* packet, void ProtobufVideoWriter::ProcessVideoPacket(const VideoPacket* packet,
......
...@@ -44,6 +44,8 @@ class ProtobufVideoWriter : public VideoWriter { ...@@ -44,6 +44,8 @@ class ProtobufVideoWriter : public VideoWriter {
private: private:
void OnChannelReady(net::StreamSocket* socket); void OnChannelReady(net::StreamSocket* socket);
Session* session_;
InitializedCallback initialized_callback_; InitializedCallback initialized_callback_;
// TODO(sergeyu): Remove |channel_| and let |buffered_writer_| own it. // TODO(sergeyu): Remove |channel_| and let |buffered_writer_| own it.
......
...@@ -107,6 +107,7 @@ class MockSession : public Session { ...@@ -107,6 +107,7 @@ class MockSession : public Session {
const std::string& name, const StreamChannelCallback& callback)); const std::string& name, const StreamChannelCallback& callback));
MOCK_METHOD2(CreateDatagramChannel, void( MOCK_METHOD2(CreateDatagramChannel, void(
const std::string& name, const DatagramChannelCallback& callback)); const std::string& name, const DatagramChannelCallback& callback));
MOCK_METHOD1(CancelChannelCreation, void(const std::string& name));
MOCK_METHOD0(control_channel, net::Socket*()); MOCK_METHOD0(control_channel, net::Socket*());
MOCK_METHOD0(event_channel, net::Socket*()); MOCK_METHOD0(event_channel, net::Socket*());
MOCK_METHOD0(video_channel, net::Socket*()); MOCK_METHOD0(video_channel, net::Socket*());
......
...@@ -24,27 +24,33 @@ RtpVideoReader::PacketsQueueEntry::PacketsQueueEntry() ...@@ -24,27 +24,33 @@ RtpVideoReader::PacketsQueueEntry::PacketsQueueEntry()
} }
RtpVideoReader::RtpVideoReader(base::MessageLoopProxy* message_loop) RtpVideoReader::RtpVideoReader(base::MessageLoopProxy* message_loop)
: initialized_(false), : session_(NULL),
initialized_(false),
rtcp_writer_(message_loop), rtcp_writer_(message_loop),
last_sequence_number_(0), last_sequence_number_(0),
video_stub_(NULL) { video_stub_(NULL) {
} }
RtpVideoReader::~RtpVideoReader() { RtpVideoReader::~RtpVideoReader() {
if (session_) {
session_->CancelChannelCreation(kVideoRtpChannelName);
session_->CancelChannelCreation(kVideoRtcpChannelName);
}
ResetQueue(); ResetQueue();
} }
void RtpVideoReader::Init(protocol::Session* session, void RtpVideoReader::Init(protocol::Session* session,
VideoStub* video_stub, VideoStub* video_stub,
const InitializedCallback& callback) { const InitializedCallback& callback) {
session_ = session;
initialized_callback_ = callback; initialized_callback_ = callback;
video_stub_ = video_stub; video_stub_ = video_stub;
session->CreateDatagramChannel( session_->CreateDatagramChannel(
kVideoRtpChannelName, kVideoRtpChannelName,
base::Bind(&RtpVideoReader::OnChannelReady, base::Bind(&RtpVideoReader::OnChannelReady,
base::Unretained(this), true)); base::Unretained(this), true));
session->CreateDatagramChannel( session_->CreateDatagramChannel(
kVideoRtcpChannelName, kVideoRtcpChannelName,
base::Bind(&RtpVideoReader::OnChannelReady, base::Bind(&RtpVideoReader::OnChannelReady,
base::Unretained(this), false)); base::Unretained(this), false));
......
...@@ -68,6 +68,8 @@ class RtpVideoReader : public VideoReader { ...@@ -68,6 +68,8 @@ class RtpVideoReader : public VideoReader {
// |kReceiverReportsIntervalMs|. // |kReceiverReportsIntervalMs|.
void SendReceiverReportIf(); void SendReceiverReportIf();
Session* session_;
bool initialized_; bool initialized_;
InitializedCallback initialized_callback_; InitializedCallback initialized_callback_;
......
// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
...@@ -21,7 +21,8 @@ const int kMtu = 1200; ...@@ -21,7 +21,8 @@ const int kMtu = 1200;
} // namespace } // namespace
RtpVideoWriter::RtpVideoWriter(base::MessageLoopProxy* message_loop) RtpVideoWriter::RtpVideoWriter(base::MessageLoopProxy* message_loop)
: initialized_(false), : session_(NULL),
initialized_(false),
rtp_writer_(message_loop) { rtp_writer_(message_loop) {
} }
...@@ -31,6 +32,7 @@ RtpVideoWriter::~RtpVideoWriter() { ...@@ -31,6 +32,7 @@ RtpVideoWriter::~RtpVideoWriter() {
void RtpVideoWriter::Init(protocol::Session* session, void RtpVideoWriter::Init(protocol::Session* session,
const InitializedCallback& callback) { const InitializedCallback& callback) {
session_ = session;
initialized_callback_ = callback; initialized_callback_ = callback;
session->CreateDatagramChannel( session->CreateDatagramChannel(
kVideoRtpChannelName, kVideoRtpChannelName,
...@@ -72,6 +74,11 @@ void RtpVideoWriter::Close() { ...@@ -72,6 +74,11 @@ void RtpVideoWriter::Close() {
rtp_writer_.Close(); rtp_writer_.Close();
rtp_channel_.reset(); rtp_channel_.reset();
rtcp_channel_.reset(); rtcp_channel_.reset();
if (session_) {
session_->CancelChannelCreation(kVideoRtpChannelName);
session_->CancelChannelCreation(kVideoRtcpChannelName);
session_ = NULL;
}
} }
void RtpVideoWriter::ProcessVideoPacket(const VideoPacket* packet, void RtpVideoWriter::ProcessVideoPacket(const VideoPacket* packet,
......
// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
...@@ -24,7 +24,7 @@ class RtpVideoWriter : public VideoWriter { ...@@ -24,7 +24,7 @@ class RtpVideoWriter : public VideoWriter {
virtual ~RtpVideoWriter(); virtual ~RtpVideoWriter();
// VideoWriter interface. // VideoWriter interface.
virtual void Init(protocol::Session* session, virtual void Init(Session* session,
const InitializedCallback& callback) OVERRIDE; const InitializedCallback& callback) OVERRIDE;
virtual void Close() OVERRIDE; virtual void Close() OVERRIDE;
...@@ -36,6 +36,8 @@ class RtpVideoWriter : public VideoWriter { ...@@ -36,6 +36,8 @@ class RtpVideoWriter : public VideoWriter {
private: private:
void OnChannelReady(bool rtp, net::Socket* socket); void OnChannelReady(bool rtp, net::Socket* socket);
Session* session_;
bool initialized_; bool initialized_;
InitializedCallback initialized_callback_; InitializedCallback initialized_callback_;
......
...@@ -90,6 +90,11 @@ class Session : public base::NonThreadSafe { ...@@ -90,6 +90,11 @@ class Session : public base::NonThreadSafe {
virtual void CreateDatagramChannel( virtual void CreateDatagramChannel(
const std::string& name, const DatagramChannelCallback& callback) = 0; const std::string& name, const DatagramChannelCallback& callback) = 0;
// Cancels a pending CreateStreamChannel() or CreateDatagramChannel()
// operation for the named channel. If the channel creation already
// completed then cancelling it has no effect.
virtual void CancelChannelCreation(const std::string& name) = 0;
// TODO(sergeyu): Remove these methods, and use CreateChannel() // TODO(sergeyu): Remove these methods, and use CreateChannel()
// instead. // instead.
virtual net::Socket* control_channel() = 0; virtual net::Socket* control_channel() = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment