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

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

Issue 6820057: Added TCPServerSocket. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: windows, fixes for mac Created 9 years, 8 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) 2011 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_win.h"
6
7 #include <mstcpip.h>
8
9 #include "base/eintr_wrapper.h"
10 #include "net/base/ip_endpoint.h"
11 #include "net/base/net_errors.h"
12 #include "net/base/net_util.h"
13 #include "net/base/winsock_init.h"
14 #include "net/base/winsock_util.h"
15
16 namespace net {
17
18 TCPServerSocketWin::TCPServerSocketWin(net::NetLog* net_log,
19 const net::NetLog::Source& source)
20 : socket_(INVALID_SOCKET),
21 socket_event_(WSA_INVALID_EVENT),
22 accept_socket_(NULL),
23 accept_address_(NULL),
24 accept_callback_(NULL),
25 net_log_(net_log),
26 net_log_source_(source) {
27 EnsureWinsockInit();
28 }
29
30 TCPServerSocketWin::~TCPServerSocketWin() {
31 if (socket_ != INVALID_SOCKET) {
32 closesocket(socket_);
33 socket_ = INVALID_SOCKET;
34 }
35
36 if (socket_event_) {
37 WSACloseEvent(socket_event_);
38 socket_event_ = WSA_INVALID_EVENT;
39 }
40 }
41
42 int TCPServerSocketWin::Bind(const IPEndPoint& address, int backlog) {
43 DCHECK(CalledOnValidThread());
44 DCHECK_GT(backlog, 0);
45 DCHECK_EQ(socket_, INVALID_SOCKET);
46 DCHECK_EQ(socket_event_, WSA_INVALID_EVENT);
47
48 socket_event_ = WSACreateEvent();
49 if (socket_event_ == WSA_INVALID_EVENT) {
50 PLOG(ERROR) << "WSACreateEvent()";
51 return ERR_FAILED;
52 }
53
54 socket_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
55 if (socket_ < 0) {
56 PLOG(ERROR) << "socket() returned an error";
57 return MapSystemError(WSAGetLastError());
58 }
59
60 if (SetNonBlocking(socket_)) {
61 int result = MapSystemError(WSAGetLastError());
62 closesocket(socket_);
63 return result;
64 }
65
66 struct sockaddr_storage addr_storage;
67 size_t addr_len = sizeof(addr_storage);
68 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage);
69 if (!address.ToSockAddr(addr, &addr_len))
70 return ERR_INVALID_ARGUMENT;
71
72 int result = bind(socket_, addr, addr_len);
73 if (result < 0) {
74 PLOG(ERROR) << "bind() returned an error";
75 result = MapSystemError(WSAGetLastError());
76 closesocket(socket_);
77 socket_ = INVALID_SOCKET;
78 return result;
79 }
80
81 result = listen(socket_, backlog);
82 if (result < 0) {
83 PLOG(ERROR) << "listen() returned an error";
84 result = MapSystemError(WSAGetLastError());
85 closesocket(socket_);
86 socket_ = INVALID_SOCKET;
87 return result;
88 }
89
90 return OK;
91 }
92
93 int TCPServerSocketWin::GetLocalAddress(IPEndPoint* address) const {
94 DCHECK(CalledOnValidThread());
95 DCHECK(address);
96
97 struct sockaddr_storage addr_storage;
98 socklen_t addr_len = sizeof(addr_storage);
99 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage);
100 if (getsockname(socket_, addr, &addr_len))
101 return MapSystemError(WSAGetLastError());
102 if (!address->FromSockAddr(addr, addr_len))
103 return ERR_FAILED;
104
105 return OK;
106 }
107
108 int TCPServerSocketWin::Accept(
109 TCPClientSocket** socket, net::IPEndPoint* address,
110 CompletionCallback* callback) {
111 DCHECK(CalledOnValidThread());
112 DCHECK(socket);
113 DCHECK(address);
114 DCHECK(callback);
115 DCHECK(!accept_callback_);
116
117 int result = AcceptInternal(socket, address);
118
119 if (result == ERR_IO_PENDING) {
120 // Start watching
121 WSAEventSelect(socket_, socket_event_, FD_ACCEPT);
122 accept_watcher_.StartWatching(socket_event_, this);
123
124 accept_socket_ = socket;
125 accept_address_ = address;
126 accept_callback_ = callback;
127 }
128
129 return result;
130 }
131
132 int TCPServerSocketWin::AcceptInternal(
133 TCPClientSocket** socket, net::IPEndPoint* address) {
134 struct sockaddr_storage addr_storage;
135 socklen_t addr_len = sizeof(addr_storage);
136 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage);
137
138 int result = accept(socket_, addr, &addr_len);
139 if (result < 0)
140 return MapSystemError(WSAGetLastError());
141
142 if (!address->FromSockAddr(addr, addr_len)) {
143 NOTREACHED();
144 closesocket(result);
145 return ERR_FAILED;
146 }
147 *socket = new TCPClientSocket(AddressList(), net_log_, net_log_source_);
148 (*socket)->AdoptSocket(result);
149 return OK;
150 }
151
152 void TCPServerSocketWin::OnObjectSignaled(HANDLE object) {
153 WSANETWORKEVENTS ev;
154 if (WSAEnumNetworkEvents(socket_, socket_event_, &ev) == SOCKET_ERROR) {
155 PLOG(ERROR) << "WSAEnumNetworkEvents()";
156 return;
157 }
158
159 if (ev.lNetworkEvents & FD_ACCEPT) {
160 int result = AcceptInternal(accept_socket_, accept_address_);
161 if (result == 0) {
162 CompletionCallback* c = accept_callback_;
163 accept_callback_ = NULL;
164 accept_socket_ = NULL;
165 accept_address_ = NULL;
166 c->Run(0);
167 } else {
168 PLOG(ERROR) << "accept() returned error after accept event was signalled";
169 }
170 }
171 }
172
173 } // namespace net
OLDNEW
« net/socket/tcp_server_socket_libevent.cc ('K') | « net/socket/tcp_server_socket_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698