1 // Copyright 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.
5 #include "net/socket/tcp_server_socket.h"
8 #include "base/bind_helpers.h"
9 #include "base/logging.h"
10 #include "net/base/net_errors.h"
11 #include "net/socket/tcp_client_socket.h"
15 TCPServerSocket::TCPServerSocket(NetLog
* net_log
, const NetLog::Source
& source
)
16 : socket_(net_log
, source
),
17 pending_accept_(false) {
20 TCPServerSocket::~TCPServerSocket() {
23 int TCPServerSocket::Listen(const IPEndPoint
& address
, int backlog
) {
24 int result
= socket_
.Open(address
.GetFamily());
28 result
= socket_
.SetDefaultOptionsForServer();
34 result
= socket_
.Bind(address
);
40 result
= socket_
.Listen(backlog
);
49 int TCPServerSocket::GetLocalAddress(IPEndPoint
* address
) const {
50 return socket_
.GetLocalAddress(address
);
53 int TCPServerSocket::Accept(scoped_ptr
<StreamSocket
>* socket
,
54 const CompletionCallback
& callback
) {
56 DCHECK(!callback
.is_null());
58 if (pending_accept_
) {
60 return ERR_UNEXPECTED
;
63 // It is safe to use base::Unretained(this). |socket_| is owned by this class,
64 // and the callback won't be run after |socket_| is destroyed.
65 CompletionCallback accept_callback
=
66 base::Bind(&TCPServerSocket::OnAcceptCompleted
, base::Unretained(this),
68 int result
= socket_
.Accept(&accepted_socket_
, &accepted_address_
,
70 if (result
!= ERR_IO_PENDING
) {
71 // |accept_callback| won't be called so we need to run
72 // ConvertAcceptedSocket() ourselves in order to do the conversion from
73 // |accepted_socket_| to |socket|.
74 result
= ConvertAcceptedSocket(result
, socket
);
76 pending_accept_
= true;
82 int TCPServerSocket::ConvertAcceptedSocket(
84 scoped_ptr
<StreamSocket
>* output_accepted_socket
) {
85 // Make sure the TCPSocket object is destroyed in any case.
86 scoped_ptr
<TCPSocket
> temp_accepted_socket(accepted_socket_
.Pass());
90 output_accepted_socket
->reset(new TCPClientSocket(
91 temp_accepted_socket
.Pass(), accepted_address_
));
96 void TCPServerSocket::OnAcceptCompleted(
97 scoped_ptr
<StreamSocket
>* output_accepted_socket
,
98 const CompletionCallback
& forward_callback
,
100 result
= ConvertAcceptedSocket(result
, output_accepted_socket
);
101 pending_accept_
= false;
102 forward_callback
.Run(result
);