MD Downloads: center "Open downloads folder" when there's no downloads
[chromium-blink-merge.git] / remoting / protocol / pseudotcp_channel_factory.cc
blob432a2a92967261882dd66c7f48b2b275edc4f07c
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "remoting/protocol/pseudotcp_channel_factory.h"
7 #include "base/bind.h"
8 #include "net/base/net_errors.h"
9 #include "remoting/base/constants.h"
10 #include "remoting/protocol/datagram_channel_factory.h"
11 #include "remoting/protocol/p2p_datagram_socket.h"
12 #include "remoting/protocol/pseudotcp_adapter.h"
14 namespace remoting {
15 namespace protocol {
17 namespace {
19 // Value is chosen to balance the extra latency against the reduced
20 // load due to ACK traffic.
21 const int kTcpAckDelayMilliseconds = 10;
23 // Values for the TCP send and receive buffer size. This should be tuned to
24 // accommodate high latency network but not backlog the decoding pipeline.
25 const int kTcpReceiveBufferSize = 256 * 1024;
26 const int kTcpSendBufferSize = kTcpReceiveBufferSize + 30 * 1024;
28 } // namespace
30 PseudoTcpChannelFactory::PseudoTcpChannelFactory(
31 DatagramChannelFactory* datagram_channel_factory)
32 : datagram_channel_factory_(datagram_channel_factory) {
35 PseudoTcpChannelFactory::~PseudoTcpChannelFactory() {
36 // CancelChannelCreation() is expected to be called before destruction.
37 DCHECK(pending_sockets_.empty());
40 void PseudoTcpChannelFactory::CreateChannel(
41 const std::string& name,
42 const ChannelCreatedCallback& callback) {
43 datagram_channel_factory_->CreateChannel(
44 name,
45 base::Bind(&PseudoTcpChannelFactory::OnDatagramChannelCreated,
46 base::Unretained(this), name, callback));
49 void PseudoTcpChannelFactory::CancelChannelCreation(const std::string& name) {
50 PendingSocketsMap::iterator it = pending_sockets_.find(name);
51 if (it == pending_sockets_.end()) {
52 datagram_channel_factory_->CancelChannelCreation(name);
53 } else {
54 delete it->second;
55 pending_sockets_.erase(it);
59 void PseudoTcpChannelFactory::OnDatagramChannelCreated(
60 const std::string& name,
61 const ChannelCreatedCallback& callback,
62 scoped_ptr<P2PDatagramSocket> datagram_socket) {
63 PseudoTcpAdapter* adapter = new PseudoTcpAdapter(datagram_socket.Pass());
64 pending_sockets_[name] = adapter;
66 adapter->SetSendBufferSize(kTcpSendBufferSize);
67 adapter->SetReceiveBufferSize(kTcpReceiveBufferSize);
68 adapter->SetNoDelay(true);
69 adapter->SetAckDelay(kTcpAckDelayMilliseconds);
71 // TODO(sergeyu): This is a hack to improve latency of the video channel.
72 // Consider removing it once we have better flow control implemented.
73 if (name == kVideoChannelName)
74 adapter->SetWriteWaitsForSend(true);
76 int result = adapter->Connect(
77 base::Bind(&PseudoTcpChannelFactory::OnPseudoTcpConnected,
78 base::Unretained(this), name, callback));
79 if (result != net::ERR_IO_PENDING)
80 OnPseudoTcpConnected(name, callback, result);
83 void PseudoTcpChannelFactory::OnPseudoTcpConnected(
84 const std::string& name,
85 const ChannelCreatedCallback& callback,
86 int result) {
87 PendingSocketsMap::iterator it = pending_sockets_.find(name);
88 DCHECK(it != pending_sockets_.end());
89 scoped_ptr<P2PStreamSocket> socket(it->second);
90 pending_sockets_.erase(it);
92 if (result != net::OK)
93 socket.reset();
95 callback.Run(socket.Pass());
98 } // namespace protocol
99 } // namespace remoting