Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(223)

Side by Side Diff: net/socket/tcp_server_socket.cc

Issue 22861033: Move server socket functionality from TCPServerSocket into TCPSocket. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2013 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.
4
5 #include "net/socket/tcp_server_socket.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/logging.h"
10 #include "build/build_config.h"
11 #include "net/base/net_errors.h"
12 #include "net/socket/tcp_client_socket.h"
13
14 namespace net {
15
16 TCPServerSocket::TCPServerSocket(NetLog* net_log, const NetLog::Source& source)
17 : socket_(net_log, source),
18 pending_accept_(false) {
19 }
20
21 TCPServerSocket::~TCPServerSocket() {
22 }
23
24 int TCPServerSocket::Listen(const IPEndPoint& address, int backlog) {
25 int result = socket_.Create(address.GetFamily());
26 if (result != OK)
27 return result;
28
29 #if defined(WIN)
30 result = socket_.SetExclusiveAddrUse();
akalin 2013/08/26 23:48:51 ideally this platform difference would be abstract
yzshen1 2013/08/27 17:36:56 Yeah, I wish to do it later. I added a TODO.
yzshen1 2013/08/27 22:54:26 After a second thought, I just did it in this CL b
31 #elif defined(POSIX)
32 result = socket_.SetAddressReuse(true);
33 #endif
34 if (result != OK ||
35 (result = socket_.Bind(address)) != OK ||
akalin 2013/08/26 23:48:51 assignments in conditionals are against the style
yzshen1 2013/08/27 17:36:56 It doesn't seem to worth the effort to add Swap()
36 (result = socket_.Listen(backlog)) != OK) {
37 socket_.Close();
38 return result;
39 }
40
41 return OK;
42 }
43
44 int TCPServerSocket::GetLocalAddress(IPEndPoint* address) const {
45 return socket_.GetLocalAddress(address);
46 }
47
48 int TCPServerSocket::Accept(scoped_ptr<StreamSocket>* socket,
49 const CompletionCallback& callback) {
50 DCHECK(socket);
51 DCHECK(!callback.is_null());
52 DCHECK(!pending_accept_);
53
54 pending_accept_ = true;
55
56 // It is safe to use base::Unretained(this). |socket_| is owned by this class,
57 // and the callback won't be run after |socket_| is destroyed.
58 CompletionCallback accept_callback = base::Bind(
59 base::Bind(&TCPServerSocket::OnAcceptCompleted, base::Unretained(this),
akalin 2013/08/26 23:48:51 you're doing Bind() twice!
yzshen1 2013/08/27 17:36:56 Oops. :) On 2013/08/26 23:48:51, akalin wrote:
60 socket, callback));
akalin 2013/08/26 23:48:51 line up socket with &TCPServerSocket
yzshen1 2013/08/27 17:36:56 Done.
61 int result = socket_.Accept(&accepted_socket_, &accepted_address_,
62 accept_callback);
63 if (result != ERR_IO_PENDING) {
64 // |accept_callback| won't be called so we need to run OnAcceptCompleted()
65 // ourselves in order to do the conversion from |accepted_socket_| to
66 // |socket|. We don't want to run |callback| in this case, so we use a null
67 // CompletionCallback.
68 OnAcceptCompleted(socket, CompletionCallback(), result);
69 }
70
71 return result;
72 }
73
74 void TCPServerSocket::OnAcceptCompleted(
75 scoped_ptr<StreamSocket>* output_accepted_socket,
76 const CompletionCallback& forward_callback,
77 int result) {
78 do {
79 if (result != OK)
akalin 2013/08/26 23:48:51 Can you decomp the body of the do/while loop into
yzshen1 2013/08/27 17:36:56 Thanks, this is a good idea. Done. On 2013/08/26
80 break;
81
82 scoped_ptr<TCPClientSocket> client_socket(new TCPClientSocket(
83 AddressList(accepted_address_),
84 accepted_socket_->net_log().net_log(),
85 accepted_socket_->net_log().source()));
86 // TODO(yzshen): Once we switch TCPClientSocket::AdoptSocket() to take a
87 // TCPSocket object, we don't need to do platform-specific handling.
88 #if defined(OS_WIN)
89 SOCKET raw_socket = accepted_socket_->Release();
90 #elif defined(OS_POSIX)
91 int raw_socket = accepted_socket_->Release();
92 #endif
93 result = client_socket->AdoptSocket(raw_socket);
94 if (result != OK) {
95 // |client_socket| won't take ownership of |raw_socket| on failure.
96 // Therefore, we put it back into |accepted_socket_| to close it.
97 accepted_socket_->Adopt(raw_socket);
98 break;
99 }
100
101 *output_accepted_socket = client_socket.Pass();
102 } while (false);
103
104 accepted_socket_.reset();
105 pending_accept_ = false;
106 if (!forward_callback.is_null())
107 forward_callback.Run(result);
108 }
109
110 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698