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

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

Issue 10907154: Allow server sockets to rebind to same port if there is nothing actively listening on that port. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remove bitmap Created 8 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/socket/tcp_server_socket_libevent.h" 5 #include "net/socket/tcp_server_socket_libevent.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <netdb.h> 9 #include <netdb.h>
10 #include <sys/socket.h> 10 #include <sys/socket.h>
(...skipping 17 matching lines...) Expand all
28 28
29 const int kInvalidSocket = -1; 29 const int kInvalidSocket = -1;
30 30
31 } // namespace 31 } // namespace
32 32
33 TCPServerSocketLibevent::TCPServerSocketLibevent( 33 TCPServerSocketLibevent::TCPServerSocketLibevent(
34 net::NetLog* net_log, 34 net::NetLog* net_log,
35 const net::NetLog::Source& source) 35 const net::NetLog::Source& source)
36 : socket_(kInvalidSocket), 36 : socket_(kInvalidSocket),
37 accept_socket_(NULL), 37 accept_socket_(NULL),
38 reuse_addr_(false),
38 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) { 39 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) {
39 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, 40 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE,
40 source.ToEventParametersCallback()); 41 source.ToEventParametersCallback());
41 } 42 }
42 43
43 TCPServerSocketLibevent::~TCPServerSocketLibevent() { 44 TCPServerSocketLibevent::~TCPServerSocketLibevent() {
44 if (socket_ != kInvalidSocket) 45 if (socket_ != kInvalidSocket)
45 Close(); 46 Close();
46 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE); 47 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE);
47 } 48 }
48 49
49 int TCPServerSocketLibevent::Listen(const IPEndPoint& address, int backlog) { 50 int TCPServerSocketLibevent::Listen(const IPEndPoint& address, int backlog) {
50 DCHECK(CalledOnValidThread()); 51 DCHECK(CalledOnValidThread());
51 DCHECK_GT(backlog, 0); 52 DCHECK_GT(backlog, 0);
52 DCHECK_EQ(socket_, kInvalidSocket); 53 DCHECK_EQ(socket_, kInvalidSocket);
53 54
54 socket_ = socket(address.GetFamily(), SOCK_STREAM, IPPROTO_TCP); 55 socket_ = socket(address.GetFamily(), SOCK_STREAM, IPPROTO_TCP);
55 if (socket_ < 0) { 56 if (socket_ < 0) {
56 PLOG(ERROR) << "socket() returned an error"; 57 PLOG(ERROR) << "socket() returned an error";
57 return MapSystemError(errno); 58 return MapSystemError(errno);
58 } 59 }
59 60
60 if (SetNonBlocking(socket_)) { 61 if (SetNonBlocking(socket_)) {
61 int result = MapSystemError(errno); 62 int result = MapSystemError(errno);
62 Close(); 63 Close();
63 return result; 64 return result;
64 } 65 }
65 66
67 int result = SetSocketOptions();
68 if (result < 0) {
69 return result;
70 }
71
66 SockaddrStorage storage; 72 SockaddrStorage storage;
67 if (!address.ToSockAddr(storage.addr, &storage.addr_len)) 73 if (!address.ToSockAddr(storage.addr, &storage.addr_len))
68 return ERR_INVALID_ARGUMENT; 74 return ERR_INVALID_ARGUMENT;
69 75
70 int result = bind(socket_, storage.addr, storage.addr_len); 76 result = bind(socket_, storage.addr, storage.addr_len);
71 if (result < 0) { 77 if (result < 0) {
72 PLOG(ERROR) << "bind() returned an error"; 78 PLOG(ERROR) << "bind() returned an error";
73 result = MapSystemError(errno); 79 result = MapSystemError(errno);
74 Close(); 80 Close();
75 return result; 81 return result;
76 } 82 }
77 83
78 result = listen(socket_, backlog); 84 result = listen(socket_, backlog);
79 if (result < 0) { 85 if (result < 0) {
80 PLOG(ERROR) << "listen() returned an error"; 86 PLOG(ERROR) << "listen() returned an error";
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 CompletionCallback callback = accept_callback_; 189 CompletionCallback callback = accept_callback_;
184 accept_callback_.Reset(); 190 accept_callback_.Reset();
185 callback.Run(result); 191 callback.Run(result);
186 } 192 }
187 } 193 }
188 194
189 void TCPServerSocketLibevent::OnFileCanWriteWithoutBlocking(int fd) { 195 void TCPServerSocketLibevent::OnFileCanWriteWithoutBlocking(int fd) {
190 NOTREACHED(); 196 NOTREACHED();
191 } 197 }
192 198
199 void TCPServerSocketLibevent::AllowAddressReuse() {
Sergey Ulanov 2012/09/12 21:52:35 nit: It's best to put method implementations in th
justinlin 2012/09/13 07:12:56 Done.
200 DCHECK(CalledOnValidThread());
201 DCHECK_EQ(socket_, kInvalidSocket);
202
203 reuse_addr_ = true;
204 }
205
206 int TCPServerSocketLibevent::SetSocketOptions() {
207 int true_value = 1;
208 if (reuse_addr_) {
209 int rv = setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, &true_value,
210 sizeof(true_value));
211 if (rv < 0)
212 return MapSystemError(errno);
213 }
214 return OK;
215 }
216
193 } // namespace net 217 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698