summaryrefslogtreecommitdiffstats
path: root/remoting
diff options
context:
space:
mode:
authorsergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-30 23:23:30 +0000
committersergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-30 23:23:30 +0000
commit86dbc72dd6030f7796ac602279fab6ad85eeca60 (patch)
tree6f4eafd5ed6d7b00437f23bf2c797b841783a8b8 /remoting
parent44d461e80c337d7baa8b9b9055d3b17ee7bc66b6 (diff)
downloadchromium_src-86dbc72dd6030f7796ac602279fab6ad85eeca60.zip
chromium_src-86dbc72dd6030f7796ac602279fab6ad85eeca60.tar.gz
chromium_src-86dbc72dd6030f7796ac602279fab6ad85eeca60.tar.bz2
Close all writers before JingleSession is destroyed.
BUG=None TEST=None Review URL: http://codereview.chromium.org/7218061 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@91225 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting')
-rw-r--r--remoting/client/input_handler.cc1
-rw-r--r--remoting/client/plugin/chromoting_instance.cc1
-rw-r--r--remoting/protocol/buffered_socket_writer.cc24
-rw-r--r--remoting/protocol/buffered_socket_writer.h3
-rw-r--r--remoting/protocol/client_control_sender.cc4
-rw-r--r--remoting/protocol/client_control_sender.h8
-rw-r--r--remoting/protocol/connection_to_client.cc41
-rw-r--r--remoting/protocol/connection_to_client.h7
-rw-r--r--remoting/protocol/connection_to_client_unittest.cc17
-rw-r--r--remoting/protocol/connection_to_host.cc21
-rw-r--r--remoting/protocol/connection_to_host.h14
-rw-r--r--remoting/protocol/host_control_sender.cc4
-rw-r--r--remoting/protocol/host_control_sender.h8
-rw-r--r--remoting/protocol/input_sender.cc4
-rw-r--r--remoting/protocol/input_sender.h7
-rw-r--r--remoting/protocol/protobuf_video_writer.cc4
-rw-r--r--remoting/protocol/protobuf_video_writer.h9
-rw-r--r--remoting/protocol/rtcp_writer.cc7
-rw-r--r--remoting/protocol/rtcp_writer.h1
-rw-r--r--remoting/protocol/rtp_video_reader_unittest.cc3
-rw-r--r--remoting/protocol/rtp_video_writer.cc8
-rw-r--r--remoting/protocol/rtp_video_writer.h8
-rw-r--r--remoting/protocol/rtp_video_writer_unittest.cc3
-rw-r--r--remoting/protocol/rtp_writer.cc4
-rw-r--r--remoting/protocol/rtp_writer.h1
-rw-r--r--remoting/protocol/video_writer.h5
26 files changed, 159 insertions, 58 deletions
diff --git a/remoting/client/input_handler.cc b/remoting/client/input_handler.cc
index c203f54..1dddc0a 100644
--- a/remoting/client/input_handler.cc
+++ b/remoting/client/input_handler.cc
@@ -7,6 +7,7 @@
#include "remoting/client/chromoting_view.h"
#include "remoting/proto/event.pb.h"
#include "remoting/protocol/connection_to_host.h"
+#include "remoting/protocol/input_stub.h"
namespace remoting {
diff --git a/remoting/client/plugin/chromoting_instance.cc b/remoting/client/plugin/chromoting_instance.cc
index 459c701..b44f59037 100644
--- a/remoting/client/plugin/chromoting_instance.cc
+++ b/remoting/client/plugin/chromoting_instance.cc
@@ -38,6 +38,7 @@
#include "remoting/jingle_glue/jingle_thread.h"
#include "remoting/proto/auth.pb.h"
#include "remoting/protocol/connection_to_host.h"
+#include "remoting/protocol/host_stub.h"
// TODO(sergeyu): This is a hack: plugin should not depend on webkit
// glue. It is used here to get P2PPacketDispatcher corresponding to
// the current RenderView. Use P2P Pepper API for connection and
diff --git a/remoting/protocol/buffered_socket_writer.cc b/remoting/protocol/buffered_socket_writer.cc
index db069b2..4da41d7 100644
--- a/remoting/protocol/buffered_socket_writer.cc
+++ b/remoting/protocol/buffered_socket_writer.cc
@@ -56,11 +56,11 @@ void BufferedSocketWriterBase::Init(net::Socket* socket,
bool BufferedSocketWriterBase::Write(
scoped_refptr<net::IOBufferWithSize> data, Task* done_task) {
- base::AutoLock auto_lock(lock_);
- if (!socket_)
- return false;
- queue_.push_back(new PendingPacket(data, done_task));
- buffer_size_ += data->size();
+ {
+ base::AutoLock auto_lock(lock_);
+ queue_.push_back(new PendingPacket(data, done_task));
+ buffer_size_ += data->size();
+ }
message_loop_->PostTask(
FROM_HERE, NewRunnableMethod(this, &BufferedSocketWriterBase::DoWrite));
return true;
@@ -75,11 +75,8 @@ void BufferedSocketWriterBase::DoWrite() {
return;
// Don't write after Close().
- {
- base::AutoLock auto_lock(lock_);
- if (closed_)
- return;
- }
+ if (closed_)
+ return;
while (true) {
net::IOBuffer* current_packet;
@@ -133,8 +130,11 @@ void BufferedSocketWriterBase::OnWritten(int result) {
}
void BufferedSocketWriterBase::HandleError(int result) {
- base::AutoLock auto_lock(lock_);
+ DCHECK_EQ(message_loop_, MessageLoop::current());
+
closed_ = true;
+
+ base::AutoLock auto_lock(lock_);
STLDeleteElements(&queue_);
// Notify subclass that an error is received.
@@ -152,7 +152,7 @@ int BufferedSocketWriterBase::GetBufferChunks() {
}
void BufferedSocketWriterBase::Close() {
- base::AutoLock auto_lock(lock_);
+ DCHECK_EQ(message_loop_, MessageLoop::current());
closed_ = true;
}
diff --git a/remoting/protocol/buffered_socket_writer.h b/remoting/protocol/buffered_socket_writer.h
index 1249080..46a3a7e 100644
--- a/remoting/protocol/buffered_socket_writer.h
+++ b/remoting/protocol/buffered_socket_writer.h
@@ -55,7 +55,8 @@ class BufferedSocketWriterBase
// to be written. Can be called on any thread.
int GetBufferChunks();
- // Stops writing and drops current buffers.
+ // Stops writing and drops current buffers. Must be called on the
+ // network thread.
void Close();
protected:
diff --git a/remoting/protocol/client_control_sender.cc b/remoting/protocol/client_control_sender.cc
index e5cda49..dbefa21 100644
--- a/remoting/protocol/client_control_sender.cc
+++ b/remoting/protocol/client_control_sender.cc
@@ -39,5 +39,9 @@ void ClientControlSender::BeginSessionResponse(const LocalLoginStatus* msg,
buffered_writer_->Write(SerializeAndFrameMessage(message), done);
}
+void ClientControlSender::Close() {
+ buffered_writer_->Close();
+}
+
} // namespace protocol
} // namespace remoting
diff --git a/remoting/protocol/client_control_sender.h b/remoting/protocol/client_control_sender.h
index 08b8f82..763ae9a 100644
--- a/remoting/protocol/client_control_sender.h
+++ b/remoting/protocol/client_control_sender.h
@@ -27,9 +27,11 @@ namespace protocol {
class BufferedSocketWriter;
+// Implementation of ClientStub that sends commands on a socket. Must
+// be created and closed on the network thread, but can be used on any
+// other thread.
class ClientControlSender : public ClientStub {
public:
- // Create a stub using a socket.
explicit ClientControlSender(net::Socket* socket);
virtual ~ClientControlSender();
@@ -38,6 +40,10 @@ class ClientControlSender : public ClientStub {
virtual void BeginSessionResponse(const LocalLoginStatus* msg,
Task* done);
+ // Stop writing. Must be called on the network thread when the
+ // underlying socket is being destroyed.
+ void Close();
+
private:
// Buffered socket writer holds the serialized message and send it on the
// right thread.
diff --git a/remoting/protocol/connection_to_client.cc b/remoting/protocol/connection_to_client.cc
index ee2131a..16795b7 100644
--- a/remoting/protocol/connection_to_client.cc
+++ b/remoting/protocol/connection_to_client.cc
@@ -57,6 +57,8 @@ void ConnectionToClient::Disconnect() {
return;
}
+ CloseChannels();
+
// If there is a channel then close it and release the reference.
if (session_) {
session_->Close(NewRunnableMethod(this, &ConnectionToClient::OnClosed));
@@ -74,7 +76,7 @@ VideoStub* ConnectionToClient::video_stub() {
// Return pointer to ClientStub.
ClientStub* ConnectionToClient::client_stub() {
- return client_stub_.get();
+ return client_control_sender_.get();
}
void ConnectionToClient::set_host_stub(protocol::HostStub* host_stub) {
@@ -86,26 +88,6 @@ void ConnectionToClient::set_input_stub(protocol::InputStub* input_stub) {
}
void ConnectionToClient::OnSessionStateChange(protocol::Session::State state) {
- if (state == protocol::Session::CONNECTED) {
- client_stub_.reset(new ClientControlSender(session_->control_channel()));
- video_writer_.reset(VideoWriter::Create(session_->config()));
- video_writer_->Init(session_);
-
- dispatcher_.reset(new HostMessageDispatcher());
- dispatcher_->Initialize(this, host_stub_, input_stub_);
- }
-
- // This method can be called from main thread so perform threading switching.
- if (MessageLoop::current() != loop_) {
- loop_->PostTask(
- FROM_HERE,
- NewRunnableMethod(this, &ConnectionToClient::StateChangeTask, state));
- } else {
- StateChangeTask(state);
- }
-}
-
-void ConnectionToClient::StateChangeTask(protocol::Session::State state) {
DCHECK_EQ(loop_, MessageLoop::current());
DCHECK(handler_);
@@ -114,12 +96,22 @@ void ConnectionToClient::StateChangeTask(protocol::Session::State state) {
break;
// Don't care about this message.
case protocol::Session::CONNECTED:
+ client_control_sender_.reset(
+ new ClientControlSender(session_->control_channel()));
+ video_writer_.reset(VideoWriter::Create(session_->config()));
+ video_writer_->Init(session_);
+
+ dispatcher_.reset(new HostMessageDispatcher());
+ dispatcher_->Initialize(this, host_stub_, input_stub_);
+
handler_->OnConnectionOpened(this);
break;
case protocol::Session::CLOSED:
+ CloseChannels();
handler_->OnConnectionClosed(this);
break;
case protocol::Session::FAILED:
+ CloseChannels();
handler_->OnConnectionFailed(this);
break;
default:
@@ -128,6 +120,13 @@ void ConnectionToClient::StateChangeTask(protocol::Session::State state) {
}
}
+void ConnectionToClient::CloseChannels() {
+ if (video_writer_.get())
+ video_writer_->Close();
+ if (client_control_sender_.get())
+ client_control_sender_->Close();
+}
+
// OnClosed() is used as a callback for protocol::Session::Close().
void ConnectionToClient::OnClosed() {
}
diff --git a/remoting/protocol/connection_to_client.h b/remoting/protocol/connection_to_client.h
index c3f424c..1201e78 100644
--- a/remoting/protocol/connection_to_client.h
+++ b/remoting/protocol/connection_to_client.h
@@ -18,6 +18,7 @@
namespace remoting {
namespace protocol {
+class ClientControlSender;
class ClientStub;
class HostStub;
class InputStub;
@@ -89,8 +90,8 @@ class ConnectionToClient :
// Callback for protocol Session.
void OnSessionStateChange(Session::State state);
- // Process a libjingle state change event on the |loop_|.
- void StateChangeTask(Session::State state);
+ // Stops writing in the channels.
+ void CloseChannels();
void OnClosed();
@@ -100,7 +101,7 @@ class ConnectionToClient :
scoped_ptr<VideoWriter> video_writer_;
// ClientStub for sending messages to the client.
- scoped_ptr<ClientStub> client_stub_;
+ scoped_ptr<ClientControlSender> client_control_sender_;
// The message loop that this object runs on.
MessageLoop* loop_;
diff --git a/remoting/protocol/connection_to_client_unittest.cc b/remoting/protocol/connection_to_client_unittest.cc
index bb73a8f..378ac3e 100644
--- a/remoting/protocol/connection_to_client_unittest.cc
+++ b/remoting/protocol/connection_to_client_unittest.cc
@@ -55,6 +55,8 @@ TEST_F(ConnectionToClientTest, SendUpdateStream) {
viewer_->video_stub()->ProcessVideoPacket(
packet, new DeleteTask<VideoPacket>(packet));
+ message_loop_.RunAllPending();
+
// And then close the connection to ConnectionToClient.
viewer_->Disconnect();
@@ -65,6 +67,21 @@ TEST_F(ConnectionToClientTest, SendUpdateStream) {
EXPECT_GT(session_->video_channel()->written_data().size(), 0u);
}
+TEST_F(ConnectionToClientTest, NoWriteAfterDisconnect) {
+ // Then send the actual data.
+ VideoPacket* packet = new VideoPacket();
+ viewer_->video_stub()->ProcessVideoPacket(
+ packet, new DeleteTask<VideoPacket>(packet));
+
+ // And then close the connection to ConnectionToClient.
+ viewer_->Disconnect();
+
+ message_loop_.RunAllPending();
+
+ // Nothing should be written because connection has been closed.
+ EXPECT_EQ(session_->video_channel()->written_data().size(), 0u);
+}
+
TEST_F(ConnectionToClientTest, StateChange) {
EXPECT_CALL(handler_, OnConnectionClosed(viewer_.get()));
session_->state_change_callback()->Run(protocol::Session::CLOSED);
diff --git a/remoting/protocol/connection_to_host.cc b/remoting/protocol/connection_to_host.cc
index 03f388c..ae9b9997 100644
--- a/remoting/protocol/connection_to_host.cc
+++ b/remoting/protocol/connection_to_host.cc
@@ -44,11 +44,11 @@ ConnectionToHost::~ConnectionToHost() {
}
InputStub* ConnectionToHost::input_stub() {
- return input_stub_.get();
+ return input_sender_.get();
}
HostStub* ConnectionToHost::host_stub() {
- return host_stub_.get();
+ return host_control_sender_.get();
}
void ConnectionToHost::Connect(scoped_refptr<XmppProxy> xmpp_proxy,
@@ -84,6 +84,8 @@ void ConnectionToHost::Disconnect(const base::Closure& shutdown_task) {
return;
}
+ CloseChannels();
+
if (session_) {
session_->Close(
NewRunnableMethod(this, &ConnectionToHost::OnDisconnected,
@@ -187,11 +189,13 @@ void ConnectionToHost::OnSessionStateChange(
switch (state) {
case Session::FAILED:
state_ = STATE_FAILED;
+ CloseChannels();
event_callback_->OnConnectionFailed(this);
break;
case Session::CLOSED:
state_ = STATE_CLOSED;
+ CloseChannels();
event_callback_->OnConnectionClosed(this);
break;
@@ -200,7 +204,8 @@ void ConnectionToHost::OnSessionStateChange(
// Initialize reader and writer.
video_reader_.reset(VideoReader::Create(session_->config()));
video_reader_->Init(session_, video_stub_);
- host_stub_.reset(new HostControlSender(session_->control_channel()));
+ host_control_sender_.reset(
+ new HostControlSender(session_->control_channel()));
dispatcher_->Initialize(session_.get(), client_stub_);
event_callback_->OnConnectionOpened(this);
break;
@@ -211,13 +216,21 @@ void ConnectionToHost::OnSessionStateChange(
}
}
+void ConnectionToHost::CloseChannels() {
+ if (input_sender_.get())
+ input_sender_->Close();
+
+ if (host_control_sender_.get())
+ host_control_sender_->Close();
+}
+
void ConnectionToHost::OnClientAuthenticated() {
// TODO(hclam): Don't send anything except authentication request if it is
// not authenticated.
state_ = STATE_AUTHENTICATED;
// Create and enable the input stub now that we're authenticated.
- input_stub_.reset(new InputSender(session_->event_channel()));
+ input_sender_.reset(new InputSender(session_->event_channel()));
}
ConnectionToHost::State ConnectionToHost::state() const {
diff --git a/remoting/protocol/connection_to_host.h b/remoting/protocol/connection_to_host.h
index 6132fb9..a943ff6 100644
--- a/remoting/protocol/connection_to_host.h
+++ b/remoting/protocol/connection_to_host.h
@@ -13,8 +13,6 @@
#include "remoting/jingle_glue/signal_strategy.h"
#include "remoting/proto/internal.pb.h"
#include "remoting/protocol/connection_to_host.h"
-#include "remoting/protocol/host_stub.h"
-#include "remoting/protocol/input_stub.h"
#include "remoting/protocol/message_reader.h"
#include "remoting/protocol/session.h"
#include "remoting/protocol/session_manager.h"
@@ -36,7 +34,12 @@ class VideoPacket;
namespace protocol {
class ClientMessageDispatcher;
+class ClientControlSender;
class ClientStub;
+class HostControlSender;
+class HostStub;
+class InputSender;
+class InputStub;
class SessionConfig;
class VideoReader;
class VideoStub;
@@ -119,6 +122,9 @@ class ConnectionToHost : public SignalStrategy::StatusObserver {
// Callback for |video_reader_|.
void OnVideoPacket(VideoPacket* packet);
+ // Stops writing in the channels.
+ void CloseChannels();
+
// Used by Disconnect() to disconnect chromoting connection, stop chromoting
// server, and then disconnect XMPP connection.
void OnDisconnected(const base::Closure& shutdown_task);
@@ -152,13 +158,13 @@ class ConnectionToHost : public SignalStrategy::StatusObserver {
// User input event channel interface
// Stub for sending input event messages to the host.
- scoped_ptr<InputStub> input_stub_;
+ scoped_ptr<InputSender> input_sender_;
////////////////////////////////////////////////////////////////////////////
// Protocol control channel interface
// Stub for sending control messages to the host.
- scoped_ptr<HostStub> host_stub_;
+ scoped_ptr<HostControlSender> host_control_sender_;
// Stub for receiving control messages from the host.
ClientStub* client_stub_;
diff --git a/remoting/protocol/host_control_sender.cc b/remoting/protocol/host_control_sender.cc
index 3f27e80..44cfceda4 100644
--- a/remoting/protocol/host_control_sender.cc
+++ b/remoting/protocol/host_control_sender.cc
@@ -39,5 +39,9 @@ void HostControlSender::BeginSessionRequest(const LocalLoginCredentials* msg,
buffered_writer_->Write(SerializeAndFrameMessage(message), done);
}
+void HostControlSender::Close() {
+ buffered_writer_->Close();
+}
+
} // namespace protocol
} // namespace remoting
diff --git a/remoting/protocol/host_control_sender.h b/remoting/protocol/host_control_sender.h
index 2cce598..a0eea33 100644
--- a/remoting/protocol/host_control_sender.h
+++ b/remoting/protocol/host_control_sender.h
@@ -27,9 +27,11 @@ namespace protocol {
class BufferedSocketWriter;
+// Implementation of HostStub that sends commands on a socket. Must be
+// created and closed on the network thread, but can be used on any
+// other thread.
class HostControlSender : public HostStub {
public:
- // Create a stub using a socket.
explicit HostControlSender(net::Socket* socket);
virtual ~HostControlSender();
@@ -38,6 +40,10 @@ class HostControlSender : public HostStub {
virtual void BeginSessionRequest(
const LocalLoginCredentials* credentials, Task* done);
+ // Stop writing. Must be called on the network thread when the
+ // underlying socket is being destroyed.
+ void Close();
+
private:
// Buffered socket writer holds the serialized message and send it on the
// right thread.
diff --git a/remoting/protocol/input_sender.cc b/remoting/protocol/input_sender.cc
index 7c9021c..dbe4d26 100644
--- a/remoting/protocol/input_sender.cc
+++ b/remoting/protocol/input_sender.cc
@@ -40,5 +40,9 @@ void InputSender::InjectMouseEvent(const MouseEvent* event, Task* done) {
buffered_writer_->Write(SerializeAndFrameMessage(message), done);
}
+void InputSender::Close() {
+ buffered_writer_->Close();
+}
+
} // namespace protocol
} // namespace remoting
diff --git a/remoting/protocol/input_sender.h b/remoting/protocol/input_sender.h
index db7bd6d02..5abcb33 100644
--- a/remoting/protocol/input_sender.h
+++ b/remoting/protocol/input_sender.h
@@ -28,6 +28,9 @@ namespace protocol {
class BufferedSocketWriter;
+// Implementation of InputStub that sends messages on a socket. Must
+// be created and closed on the network thread, but can be used on any
+// other thread.
class InputSender : public InputStub {
public:
// Create a stub using a socket.
@@ -38,6 +41,10 @@ class InputSender : public InputStub {
virtual void InjectKeyEvent(const KeyEvent* event, Task* done);
virtual void InjectMouseEvent(const MouseEvent* event, Task* done);
+ // Stop writing. Must be called on the network thread when the
+ // underlying socket is being destroyed.
+ void Close();
+
private:
// Helper method to run the task and delete it afterwards.
void RunTask(Task* done);
diff --git a/remoting/protocol/protobuf_video_writer.cc b/remoting/protocol/protobuf_video_writer.cc
index 025445d..a03a4e6 100644
--- a/remoting/protocol/protobuf_video_writer.cc
+++ b/remoting/protocol/protobuf_video_writer.cc
@@ -23,6 +23,10 @@ void ProtobufVideoWriter::Init(protocol::Session* session) {
buffered_writer_->Init(session->video_channel(), NULL);
}
+void ProtobufVideoWriter::Close() {
+ buffered_writer_->Close();
+}
+
void ProtobufVideoWriter::ProcessVideoPacket(const VideoPacket* packet,
Task* done) {
buffered_writer_->Write(SerializeAndFrameMessage(*packet), done);
diff --git a/remoting/protocol/protobuf_video_writer.h b/remoting/protocol/protobuf_video_writer.h
index aecefbc4..189eacf 100644
--- a/remoting/protocol/protobuf_video_writer.h
+++ b/remoting/protocol/protobuf_video_writer.h
@@ -5,6 +5,7 @@
#ifndef REMOTING_PROTOCOL_PROTOBUF_VIDEO_WRITER_H_
#define REMOTING_PROTOCOL_PROTOBUF_VIDEO_WRITER_H_
+#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "remoting/protocol/video_writer.h"
@@ -20,11 +21,13 @@ class ProtobufVideoWriter : public VideoWriter {
virtual ~ProtobufVideoWriter();
// VideoWriter interface.
- virtual void Init(protocol::Session* session);
+ virtual void Init(protocol::Session* session) OVERRIDE;
+ virtual void Close() OVERRIDE;
// VideoStub interface.
- virtual void ProcessVideoPacket(const VideoPacket* packet, Task* done);
- virtual int GetPendingPackets();
+ virtual void ProcessVideoPacket(const VideoPacket* packet,
+ Task* done) OVERRIDE;
+ virtual int GetPendingPackets() OVERRIDE;
private:
scoped_refptr<BufferedSocketWriter> buffered_writer_;
diff --git a/remoting/protocol/rtcp_writer.cc b/remoting/protocol/rtcp_writer.cc
index 1996665..5ccf748 100644
--- a/remoting/protocol/rtcp_writer.cc
+++ b/remoting/protocol/rtcp_writer.cc
@@ -16,7 +16,12 @@ namespace protocol {
RtcpWriter::RtcpWriter() {
}
-RtcpWriter::~RtcpWriter() { }
+RtcpWriter::~RtcpWriter() {
+}
+
+void RtcpWriter::Close() {
+ buffered_rtcp_writer_->Close();
+}
// Initializes the writer. Must be called on the thread the sockets
// belong to.
diff --git a/remoting/protocol/rtcp_writer.h b/remoting/protocol/rtcp_writer.h
index 1e16658..e4a7226 100644
--- a/remoting/protocol/rtcp_writer.h
+++ b/remoting/protocol/rtcp_writer.h
@@ -24,6 +24,7 @@ class RtcpWriter {
// Initializes the writer. Must be called on the thread the socket
// belongs to.
void Init(net::Socket* socket);
+ void Close();
// Sends next packet. The packet is mutated by
void SendReport(const RtcpReceiverReport& report);
diff --git a/remoting/protocol/rtp_video_reader_unittest.cc b/remoting/protocol/rtp_video_reader_unittest.cc
index f88ef76..0281c34 100644
--- a/remoting/protocol/rtp_video_reader_unittest.cc
+++ b/remoting/protocol/rtp_video_reader_unittest.cc
@@ -127,10 +127,11 @@ class RtpVideoReaderTest : public testing::Test,
}
}
+ MessageLoop message_loop_;
+
scoped_refptr<FakeSession> session_;
scoped_ptr<RtpVideoReader> reader_;
- MessageLoop message_loop_;
vector<char> data_;
vector<VideoPacket> received_packets_;
};
diff --git a/remoting/protocol/rtp_video_writer.cc b/remoting/protocol/rtp_video_writer.cc
index da16444..d5d4b75 100644
--- a/remoting/protocol/rtp_video_writer.cc
+++ b/remoting/protocol/rtp_video_writer.cc
@@ -20,12 +20,18 @@ const int kMtu = 1200;
RtpVideoWriter::RtpVideoWriter() { }
-RtpVideoWriter::~RtpVideoWriter() { }
+RtpVideoWriter::~RtpVideoWriter() {
+ Close();
+}
void RtpVideoWriter::Init(protocol::Session* session) {
rtp_writer_.Init(session->video_rtp_channel());
}
+void RtpVideoWriter::Close() {
+ rtp_writer_.Close();
+}
+
void RtpVideoWriter::ProcessVideoPacket(const VideoPacket* packet, Task* done) {
CHECK(packet->format().encoding() == VideoPacketFormat::ENCODING_VP8)
<< "Only VP8 is supported in RTP.";
diff --git a/remoting/protocol/rtp_video_writer.h b/remoting/protocol/rtp_video_writer.h
index 809ac49..d54d721 100644
--- a/remoting/protocol/rtp_video_writer.h
+++ b/remoting/protocol/rtp_video_writer.h
@@ -19,11 +19,13 @@ class RtpVideoWriter : public VideoWriter {
virtual ~RtpVideoWriter();
// VideoWriter interface.
- virtual void Init(protocol::Session* session);
+ virtual void Init(protocol::Session* session) OVERRIDE;
+ virtual void Close() OVERRIDE;
// VideoStub interface.
- virtual void ProcessVideoPacket(const VideoPacket* packet, Task* done);
- virtual int GetPendingPackets();
+ virtual void ProcessVideoPacket(const VideoPacket* packet,
+ Task* done) OVERRIDE;
+ virtual int GetPendingPackets() OVERRIDE;
private:
RtpWriter rtp_writer_;
diff --git a/remoting/protocol/rtp_video_writer_unittest.cc b/remoting/protocol/rtp_video_writer_unittest.cc
index be8d6c6..74b4ae3 100644
--- a/remoting/protocol/rtp_video_writer_unittest.cc
+++ b/remoting/protocol/rtp_video_writer_unittest.cc
@@ -107,10 +107,11 @@ class RtpVideoWriterTest : public testing::Test {
EXPECT_EQ(pos, static_cast<int>(data_.size()));
}
+ MessageLoop message_loop_;
+
scoped_refptr<FakeSession> session_;
RtpVideoWriter writer_;
- MessageLoop message_loop_;
vector<char> data_;
VideoPacket* packet_;
};
diff --git a/remoting/protocol/rtp_writer.cc b/remoting/protocol/rtp_writer.cc
index e26bdb7..fb1e1f8 100644
--- a/remoting/protocol/rtp_writer.cc
+++ b/remoting/protocol/rtp_writer.cc
@@ -29,6 +29,10 @@ void RtpWriter::Init(net::Socket* rtp_socket) {
buffered_rtp_writer_->Init(rtp_socket, NULL);
}
+void RtpWriter::Close() {
+ buffered_rtp_writer_->Close();
+}
+
void RtpWriter::SendPacket(uint32 timestamp, bool marker,
const Vp8Descriptor& vp8_descriptor,
const CompoundBuffer& payload) {
diff --git a/remoting/protocol/rtp_writer.h b/remoting/protocol/rtp_writer.h
index cd81bcf..dbf5bdd 100644
--- a/remoting/protocol/rtp_writer.h
+++ b/remoting/protocol/rtp_writer.h
@@ -23,6 +23,7 @@ class RtpWriter {
// Initializes the writer. Must be called on the thread the socket
// belongs to.
void Init(net::Socket* socket);
+ void Close();
// Sends next packet. The packet is mutated by
void SendPacket(uint32 timestamp, bool marker,
diff --git a/remoting/protocol/video_writer.h b/remoting/protocol/video_writer.h
index b9216c0..be4c715 100644
--- a/remoting/protocol/video_writer.h
+++ b/remoting/protocol/video_writer.h
@@ -19,7 +19,6 @@ namespace protocol {
class Session;
class SessionConfig;
-// TODO(sergeyu): VideoWriter should implement VideoStub interface.
class VideoWriter : public VideoStub {
public:
virtual ~VideoWriter();
@@ -29,6 +28,10 @@ class VideoWriter : public VideoStub {
// Initializes the writer.
virtual void Init(Session* session) = 0;
+ // Stops writing. Must be called on the network thread before this
+ // object is destroyed.
+ virtual void Close() = 0;
+
protected:
VideoWriter() { }