diff options
author | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-30 23:23:30 +0000 |
---|---|---|
committer | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-30 23:23:30 +0000 |
commit | 86dbc72dd6030f7796ac602279fab6ad85eeca60 (patch) | |
tree | 6f4eafd5ed6d7b00437f23bf2c797b841783a8b8 /remoting | |
parent | 44d461e80c337d7baa8b9b9055d3b17ee7bc66b6 (diff) | |
download | chromium_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')
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() { } |