OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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/socket_libevent.h" | 5 #include "net/socket/socket_posix.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <netinet/in.h> | 8 #include <netinet/in.h> |
9 #include <sys/socket.h> | 9 #include <sys/socket.h> |
10 | 10 |
11 #include "base/callback_helpers.h" | 11 #include "base/callback_helpers.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/posix/eintr_wrapper.h" | 13 #include "base/posix/eintr_wrapper.h" |
14 #include "net/base/io_buffer.h" | 14 #include "net/base/io_buffer.h" |
15 #include "net/base/ip_endpoint.h" | 15 #include "net/base/ip_endpoint.h" |
(...skipping 30 matching lines...) Expand all Loading... |
46 int net_error = MapSystemError(os_error); | 46 int net_error = MapSystemError(os_error); |
47 if (net_error == ERR_FAILED) | 47 if (net_error == ERR_FAILED) |
48 return ERR_CONNECTION_FAILED; // More specific than ERR_FAILED. | 48 return ERR_CONNECTION_FAILED; // More specific than ERR_FAILED. |
49 return net_error; | 49 return net_error; |
50 } | 50 } |
51 } | 51 } |
52 } | 52 } |
53 | 53 |
54 } // namespace | 54 } // namespace |
55 | 55 |
56 SocketLibevent::SocketLibevent() | 56 SocketPosix::SocketPosix() |
57 : socket_fd_(kInvalidSocket), | 57 : socket_fd_(kInvalidSocket), |
58 read_buf_len_(0), | 58 read_buf_len_(0), |
59 write_buf_len_(0), | 59 write_buf_len_(0), |
60 waiting_connect_(false) { | 60 waiting_connect_(false) {} |
61 } | |
62 | 61 |
63 SocketLibevent::~SocketLibevent() { | 62 SocketPosix::~SocketPosix() { |
64 Close(); | 63 Close(); |
65 } | 64 } |
66 | 65 |
67 int SocketLibevent::Open(int address_family) { | 66 int SocketPosix::Open(int address_family) { |
68 DCHECK(thread_checker_.CalledOnValidThread()); | 67 DCHECK(thread_checker_.CalledOnValidThread()); |
69 DCHECK_EQ(kInvalidSocket, socket_fd_); | 68 DCHECK_EQ(kInvalidSocket, socket_fd_); |
70 DCHECK(address_family == AF_INET || | 69 DCHECK(address_family == AF_INET || |
71 address_family == AF_INET6 || | 70 address_family == AF_INET6 || |
72 address_family == AF_UNIX); | 71 address_family == AF_UNIX); |
73 | 72 |
74 socket_fd_ = CreatePlatformSocket( | 73 socket_fd_ = CreatePlatformSocket( |
75 address_family, | 74 address_family, |
76 SOCK_STREAM, | 75 SOCK_STREAM, |
77 address_family == AF_UNIX ? 0 : IPPROTO_TCP); | 76 address_family == AF_UNIX ? 0 : IPPROTO_TCP); |
78 if (socket_fd_ < 0) { | 77 if (socket_fd_ < 0) { |
79 PLOG(ERROR) << "CreatePlatformSocket() returned an error, errno=" << errno; | 78 PLOG(ERROR) << "CreatePlatformSocket() returned an error, errno=" << errno; |
80 return MapSystemError(errno); | 79 return MapSystemError(errno); |
81 } | 80 } |
82 | 81 |
83 if (SetNonBlocking(socket_fd_)) { | 82 if (SetNonBlocking(socket_fd_)) { |
84 int rv = MapSystemError(errno); | 83 int rv = MapSystemError(errno); |
85 Close(); | 84 Close(); |
86 return rv; | 85 return rv; |
87 } | 86 } |
88 | 87 |
89 return OK; | 88 return OK; |
90 } | 89 } |
91 | 90 |
92 int SocketLibevent::AdoptConnectedSocket(SocketDescriptor socket, | 91 int SocketPosix::AdoptConnectedSocket(SocketDescriptor socket, |
93 const SockaddrStorage& address) { | 92 const SockaddrStorage& address) { |
94 DCHECK(thread_checker_.CalledOnValidThread()); | 93 DCHECK(thread_checker_.CalledOnValidThread()); |
95 DCHECK_EQ(kInvalidSocket, socket_fd_); | 94 DCHECK_EQ(kInvalidSocket, socket_fd_); |
96 | 95 |
97 socket_fd_ = socket; | 96 socket_fd_ = socket; |
98 | 97 |
99 if (SetNonBlocking(socket_fd_)) { | 98 if (SetNonBlocking(socket_fd_)) { |
100 int rv = MapSystemError(errno); | 99 int rv = MapSystemError(errno); |
101 Close(); | 100 Close(); |
102 return rv; | 101 return rv; |
103 } | 102 } |
104 | 103 |
105 SetPeerAddress(address); | 104 SetPeerAddress(address); |
106 return OK; | 105 return OK; |
107 } | 106 } |
108 | 107 |
109 SocketDescriptor SocketLibevent::ReleaseConnectedSocket() { | 108 SocketDescriptor SocketPosix::ReleaseConnectedSocket() { |
110 StopWatchingAndCleanUp(); | 109 StopWatchingAndCleanUp(); |
111 SocketDescriptor socket_fd = socket_fd_; | 110 SocketDescriptor socket_fd = socket_fd_; |
112 socket_fd_ = kInvalidSocket; | 111 socket_fd_ = kInvalidSocket; |
113 return socket_fd; | 112 return socket_fd; |
114 } | 113 } |
115 | 114 |
116 int SocketLibevent::Bind(const SockaddrStorage& address) { | 115 int SocketPosix::Bind(const SockaddrStorage& address) { |
117 DCHECK(thread_checker_.CalledOnValidThread()); | 116 DCHECK(thread_checker_.CalledOnValidThread()); |
118 DCHECK_NE(kInvalidSocket, socket_fd_); | 117 DCHECK_NE(kInvalidSocket, socket_fd_); |
119 | 118 |
120 int rv = bind(socket_fd_, address.addr, address.addr_len); | 119 int rv = bind(socket_fd_, address.addr, address.addr_len); |
121 if (rv < 0) { | 120 if (rv < 0) { |
122 PLOG(ERROR) << "bind() returned an error, errno=" << errno; | 121 PLOG(ERROR) << "bind() returned an error, errno=" << errno; |
123 return MapSystemError(errno); | 122 return MapSystemError(errno); |
124 } | 123 } |
125 | 124 |
126 return OK; | 125 return OK; |
127 } | 126 } |
128 | 127 |
129 int SocketLibevent::Listen(int backlog) { | 128 int SocketPosix::Listen(int backlog) { |
130 DCHECK(thread_checker_.CalledOnValidThread()); | 129 DCHECK(thread_checker_.CalledOnValidThread()); |
131 DCHECK_NE(kInvalidSocket, socket_fd_); | 130 DCHECK_NE(kInvalidSocket, socket_fd_); |
132 DCHECK_LT(0, backlog); | 131 DCHECK_LT(0, backlog); |
133 | 132 |
134 int rv = listen(socket_fd_, backlog); | 133 int rv = listen(socket_fd_, backlog); |
135 if (rv < 0) { | 134 if (rv < 0) { |
136 PLOG(ERROR) << "listen() returned an error, errno=" << errno; | 135 PLOG(ERROR) << "listen() returned an error, errno=" << errno; |
137 return MapSystemError(errno); | 136 return MapSystemError(errno); |
138 } | 137 } |
139 | 138 |
140 return OK; | 139 return OK; |
141 } | 140 } |
142 | 141 |
143 int SocketLibevent::Accept(scoped_ptr<SocketLibevent>* socket, | 142 int SocketPosix::Accept(scoped_ptr<SocketPosix>* socket, |
144 const CompletionCallback& callback) { | 143 const CompletionCallback& callback) { |
145 DCHECK(thread_checker_.CalledOnValidThread()); | 144 DCHECK(thread_checker_.CalledOnValidThread()); |
146 DCHECK_NE(kInvalidSocket, socket_fd_); | 145 DCHECK_NE(kInvalidSocket, socket_fd_); |
147 DCHECK(accept_callback_.is_null()); | 146 DCHECK(accept_callback_.is_null()); |
148 DCHECK(socket); | 147 DCHECK(socket); |
149 DCHECK(!callback.is_null()); | 148 DCHECK(!callback.is_null()); |
150 | 149 |
151 int rv = DoAccept(socket); | 150 int rv = DoAccept(socket); |
152 if (rv != ERR_IO_PENDING) | 151 if (rv != ERR_IO_PENDING) |
153 return rv; | 152 return rv; |
154 | 153 |
155 if (!base::MessageLoopForIO::current()->WatchFileDescriptor( | 154 if (!base::MessageLoopForIO::current()->WatchFileDescriptor( |
156 socket_fd_, true, base::MessageLoopForIO::WATCH_READ, | 155 socket_fd_, true, base::MessageLoopForIO::WATCH_READ, |
157 &accept_socket_watcher_, this)) { | 156 &accept_socket_watcher_, this)) { |
158 PLOG(ERROR) << "WatchFileDescriptor failed on accept, errno " << errno; | 157 PLOG(ERROR) << "WatchFileDescriptor failed on accept, errno " << errno; |
159 return MapSystemError(errno); | 158 return MapSystemError(errno); |
160 } | 159 } |
161 | 160 |
162 accept_socket_ = socket; | 161 accept_socket_ = socket; |
163 accept_callback_ = callback; | 162 accept_callback_ = callback; |
164 return ERR_IO_PENDING; | 163 return ERR_IO_PENDING; |
165 } | 164 } |
166 | 165 |
167 int SocketLibevent::Connect(const SockaddrStorage& address, | 166 int SocketPosix::Connect(const SockaddrStorage& address, |
168 const CompletionCallback& callback) { | 167 const CompletionCallback& callback) { |
169 DCHECK(thread_checker_.CalledOnValidThread()); | 168 DCHECK(thread_checker_.CalledOnValidThread()); |
170 DCHECK_NE(kInvalidSocket, socket_fd_); | 169 DCHECK_NE(kInvalidSocket, socket_fd_); |
171 DCHECK(!waiting_connect_); | 170 DCHECK(!waiting_connect_); |
172 DCHECK(!callback.is_null()); | 171 DCHECK(!callback.is_null()); |
173 | 172 |
174 SetPeerAddress(address); | 173 SetPeerAddress(address); |
175 | 174 |
176 int rv = DoConnect(); | 175 int rv = DoConnect(); |
177 if (rv != ERR_IO_PENDING) | 176 if (rv != ERR_IO_PENDING) |
178 return rv; | 177 return rv; |
179 | 178 |
180 if (!base::MessageLoopForIO::current()->WatchFileDescriptor( | 179 if (!base::MessageLoopForIO::current()->WatchFileDescriptor( |
181 socket_fd_, true, base::MessageLoopForIO::WATCH_WRITE, | 180 socket_fd_, true, base::MessageLoopForIO::WATCH_WRITE, |
182 &write_socket_watcher_, this)) { | 181 &write_socket_watcher_, this)) { |
183 PLOG(ERROR) << "WatchFileDescriptor failed on connect, errno " << errno; | 182 PLOG(ERROR) << "WatchFileDescriptor failed on connect, errno " << errno; |
184 return MapSystemError(errno); | 183 return MapSystemError(errno); |
185 } | 184 } |
186 | 185 |
187 write_callback_ = callback; | 186 write_callback_ = callback; |
188 waiting_connect_ = true; | 187 waiting_connect_ = true; |
189 return ERR_IO_PENDING; | 188 return ERR_IO_PENDING; |
190 } | 189 } |
191 | 190 |
192 bool SocketLibevent::IsConnected() const { | 191 bool SocketPosix::IsConnected() const { |
193 DCHECK(thread_checker_.CalledOnValidThread()); | 192 DCHECK(thread_checker_.CalledOnValidThread()); |
194 | 193 |
195 if (socket_fd_ == kInvalidSocket || waiting_connect_) | 194 if (socket_fd_ == kInvalidSocket || waiting_connect_) |
196 return false; | 195 return false; |
197 | 196 |
198 // Checks if connection is alive. | 197 // Checks if connection is alive. |
199 char c; | 198 char c; |
200 int rv = HANDLE_EINTR(recv(socket_fd_, &c, 1, MSG_PEEK)); | 199 int rv = HANDLE_EINTR(recv(socket_fd_, &c, 1, MSG_PEEK)); |
201 if (rv == 0) | 200 if (rv == 0) |
202 return false; | 201 return false; |
203 if (rv == -1 && errno != EAGAIN && errno != EWOULDBLOCK) | 202 if (rv == -1 && errno != EAGAIN && errno != EWOULDBLOCK) |
204 return false; | 203 return false; |
205 | 204 |
206 return true; | 205 return true; |
207 } | 206 } |
208 | 207 |
209 bool SocketLibevent::IsConnectedAndIdle() const { | 208 bool SocketPosix::IsConnectedAndIdle() const { |
210 DCHECK(thread_checker_.CalledOnValidThread()); | 209 DCHECK(thread_checker_.CalledOnValidThread()); |
211 | 210 |
212 if (socket_fd_ == kInvalidSocket || waiting_connect_) | 211 if (socket_fd_ == kInvalidSocket || waiting_connect_) |
213 return false; | 212 return false; |
214 | 213 |
215 // Check if connection is alive and we haven't received any data | 214 // Check if connection is alive and we haven't received any data |
216 // unexpectedly. | 215 // unexpectedly. |
217 char c; | 216 char c; |
218 int rv = HANDLE_EINTR(recv(socket_fd_, &c, 1, MSG_PEEK)); | 217 int rv = HANDLE_EINTR(recv(socket_fd_, &c, 1, MSG_PEEK)); |
219 if (rv >= 0) | 218 if (rv >= 0) |
220 return false; | 219 return false; |
221 if (errno != EAGAIN && errno != EWOULDBLOCK) | 220 if (errno != EAGAIN && errno != EWOULDBLOCK) |
222 return false; | 221 return false; |
223 | 222 |
224 return true; | 223 return true; |
225 } | 224 } |
226 | 225 |
227 int SocketLibevent::Read(IOBuffer* buf, | 226 int SocketPosix::Read(IOBuffer* buf, |
228 int buf_len, | 227 int buf_len, |
229 const CompletionCallback& callback) { | 228 const CompletionCallback& callback) { |
230 DCHECK(thread_checker_.CalledOnValidThread()); | 229 DCHECK(thread_checker_.CalledOnValidThread()); |
231 DCHECK_NE(kInvalidSocket, socket_fd_); | 230 DCHECK_NE(kInvalidSocket, socket_fd_); |
232 DCHECK(!waiting_connect_); | 231 DCHECK(!waiting_connect_); |
233 CHECK(read_callback_.is_null()); | 232 CHECK(read_callback_.is_null()); |
234 // Synchronous operation not supported | 233 // Synchronous operation not supported |
235 DCHECK(!callback.is_null()); | 234 DCHECK(!callback.is_null()); |
236 DCHECK_LT(0, buf_len); | 235 DCHECK_LT(0, buf_len); |
237 | 236 |
238 int rv = DoRead(buf, buf_len); | 237 int rv = DoRead(buf, buf_len); |
239 if (rv != ERR_IO_PENDING) | 238 if (rv != ERR_IO_PENDING) |
240 return rv; | 239 return rv; |
241 | 240 |
242 if (!base::MessageLoopForIO::current()->WatchFileDescriptor( | 241 if (!base::MessageLoopForIO::current()->WatchFileDescriptor( |
243 socket_fd_, true, base::MessageLoopForIO::WATCH_READ, | 242 socket_fd_, true, base::MessageLoopForIO::WATCH_READ, |
244 &read_socket_watcher_, this)) { | 243 &read_socket_watcher_, this)) { |
245 PLOG(ERROR) << "WatchFileDescriptor failed on read, errno " << errno; | 244 PLOG(ERROR) << "WatchFileDescriptor failed on read, errno " << errno; |
246 return MapSystemError(errno); | 245 return MapSystemError(errno); |
247 } | 246 } |
248 | 247 |
249 read_buf_ = buf; | 248 read_buf_ = buf; |
250 read_buf_len_ = buf_len; | 249 read_buf_len_ = buf_len; |
251 read_callback_ = callback; | 250 read_callback_ = callback; |
252 return ERR_IO_PENDING; | 251 return ERR_IO_PENDING; |
253 } | 252 } |
254 | 253 |
255 int SocketLibevent::Write(IOBuffer* buf, | 254 int SocketPosix::Write(IOBuffer* buf, |
256 int buf_len, | 255 int buf_len, |
257 const CompletionCallback& callback) { | 256 const CompletionCallback& callback) { |
258 DCHECK(thread_checker_.CalledOnValidThread()); | 257 DCHECK(thread_checker_.CalledOnValidThread()); |
259 DCHECK_NE(kInvalidSocket, socket_fd_); | 258 DCHECK_NE(kInvalidSocket, socket_fd_); |
260 DCHECK(!waiting_connect_); | 259 DCHECK(!waiting_connect_); |
261 CHECK(write_callback_.is_null()); | 260 CHECK(write_callback_.is_null()); |
262 // Synchronous operation not supported | 261 // Synchronous operation not supported |
263 DCHECK(!callback.is_null()); | 262 DCHECK(!callback.is_null()); |
264 DCHECK_LT(0, buf_len); | 263 DCHECK_LT(0, buf_len); |
265 | 264 |
266 int rv = DoWrite(buf, buf_len); | 265 int rv = DoWrite(buf, buf_len); |
267 if (rv == ERR_IO_PENDING) | 266 if (rv == ERR_IO_PENDING) |
268 rv = WaitForWrite(buf, buf_len, callback); | 267 rv = WaitForWrite(buf, buf_len, callback); |
269 return rv; | 268 return rv; |
270 } | 269 } |
271 | 270 |
272 int SocketLibevent::WaitForWrite(IOBuffer* buf, | 271 int SocketPosix::WaitForWrite(IOBuffer* buf, |
273 int buf_len, | 272 int buf_len, |
274 const CompletionCallback& callback) { | 273 const CompletionCallback& callback) { |
275 DCHECK(thread_checker_.CalledOnValidThread()); | 274 DCHECK(thread_checker_.CalledOnValidThread()); |
276 DCHECK_NE(kInvalidSocket, socket_fd_); | 275 DCHECK_NE(kInvalidSocket, socket_fd_); |
277 DCHECK(write_callback_.is_null()); | 276 DCHECK(write_callback_.is_null()); |
278 // Synchronous operation not supported | 277 // Synchronous operation not supported |
279 DCHECK(!callback.is_null()); | 278 DCHECK(!callback.is_null()); |
280 DCHECK_LT(0, buf_len); | 279 DCHECK_LT(0, buf_len); |
281 | 280 |
282 if (!base::MessageLoopForIO::current()->WatchFileDescriptor( | 281 if (!base::MessageLoopForIO::current()->WatchFileDescriptor( |
283 socket_fd_, true, base::MessageLoopForIO::WATCH_WRITE, | 282 socket_fd_, true, base::MessageLoopForIO::WATCH_WRITE, |
284 &write_socket_watcher_, this)) { | 283 &write_socket_watcher_, this)) { |
285 PLOG(ERROR) << "WatchFileDescriptor failed on write, errno " << errno; | 284 PLOG(ERROR) << "WatchFileDescriptor failed on write, errno " << errno; |
286 return MapSystemError(errno); | 285 return MapSystemError(errno); |
287 } | 286 } |
288 | 287 |
289 write_buf_ = buf; | 288 write_buf_ = buf; |
290 write_buf_len_ = buf_len; | 289 write_buf_len_ = buf_len; |
291 write_callback_ = callback; | 290 write_callback_ = callback; |
292 return ERR_IO_PENDING; | 291 return ERR_IO_PENDING; |
293 } | 292 } |
294 | 293 |
295 int SocketLibevent::GetLocalAddress(SockaddrStorage* address) const { | 294 int SocketPosix::GetLocalAddress(SockaddrStorage* address) const { |
296 DCHECK(thread_checker_.CalledOnValidThread()); | 295 DCHECK(thread_checker_.CalledOnValidThread()); |
297 DCHECK(address); | 296 DCHECK(address); |
298 | 297 |
299 if (getsockname(socket_fd_, address->addr, &address->addr_len) < 0) | 298 if (getsockname(socket_fd_, address->addr, &address->addr_len) < 0) |
300 return MapSystemError(errno); | 299 return MapSystemError(errno); |
301 return OK; | 300 return OK; |
302 } | 301 } |
303 | 302 |
304 int SocketLibevent::GetPeerAddress(SockaddrStorage* address) const { | 303 int SocketPosix::GetPeerAddress(SockaddrStorage* address) const { |
305 DCHECK(thread_checker_.CalledOnValidThread()); | 304 DCHECK(thread_checker_.CalledOnValidThread()); |
306 DCHECK(address); | 305 DCHECK(address); |
307 | 306 |
308 if (!HasPeerAddress()) | 307 if (!HasPeerAddress()) |
309 return ERR_SOCKET_NOT_CONNECTED; | 308 return ERR_SOCKET_NOT_CONNECTED; |
310 | 309 |
311 *address = *peer_address_; | 310 *address = *peer_address_; |
312 return OK; | 311 return OK; |
313 } | 312 } |
314 | 313 |
315 void SocketLibevent::SetPeerAddress(const SockaddrStorage& address) { | 314 void SocketPosix::SetPeerAddress(const SockaddrStorage& address) { |
316 DCHECK(thread_checker_.CalledOnValidThread()); | 315 DCHECK(thread_checker_.CalledOnValidThread()); |
317 // |peer_address_| will be non-NULL if Connect() has been called. Unless | 316 // |peer_address_| will be non-NULL if Connect() has been called. Unless |
318 // Close() is called to reset the internal state, a second call to Connect() | 317 // Close() is called to reset the internal state, a second call to Connect() |
319 // is not allowed. | 318 // is not allowed. |
320 // Please note that we don't allow a second Connect() even if the previous | 319 // Please note that we don't allow a second Connect() even if the previous |
321 // Connect() has failed. Connecting the same |socket_| again after a | 320 // Connect() has failed. Connecting the same |socket_| again after a |
322 // connection attempt failed results in unspecified behavior according to | 321 // connection attempt failed results in unspecified behavior according to |
323 // POSIX. | 322 // POSIX. |
324 DCHECK(!peer_address_); | 323 DCHECK(!peer_address_); |
325 peer_address_.reset(new SockaddrStorage(address)); | 324 peer_address_.reset(new SockaddrStorage(address)); |
326 } | 325 } |
327 | 326 |
328 bool SocketLibevent::HasPeerAddress() const { | 327 bool SocketPosix::HasPeerAddress() const { |
329 DCHECK(thread_checker_.CalledOnValidThread()); | 328 DCHECK(thread_checker_.CalledOnValidThread()); |
330 return peer_address_ != NULL; | 329 return peer_address_ != NULL; |
331 } | 330 } |
332 | 331 |
333 void SocketLibevent::Close() { | 332 void SocketPosix::Close() { |
334 DCHECK(thread_checker_.CalledOnValidThread()); | 333 DCHECK(thread_checker_.CalledOnValidThread()); |
335 | 334 |
336 StopWatchingAndCleanUp(); | 335 StopWatchingAndCleanUp(); |
337 | 336 |
338 if (socket_fd_ != kInvalidSocket) { | 337 if (socket_fd_ != kInvalidSocket) { |
339 if (IGNORE_EINTR(close(socket_fd_)) < 0) | 338 if (IGNORE_EINTR(close(socket_fd_)) < 0) |
340 PLOG(ERROR) << "close() returned an error, errno=" << errno; | 339 PLOG(ERROR) << "close() returned an error, errno=" << errno; |
341 socket_fd_ = kInvalidSocket; | 340 socket_fd_ = kInvalidSocket; |
342 } | 341 } |
343 } | 342 } |
344 | 343 |
345 void SocketLibevent::OnFileCanReadWithoutBlocking(int fd) { | 344 void SocketPosix::OnFileCanReadWithoutBlocking(int fd) { |
346 DCHECK(!accept_callback_.is_null() || !read_callback_.is_null()); | 345 DCHECK(!accept_callback_.is_null() || !read_callback_.is_null()); |
347 if (!accept_callback_.is_null()) { | 346 if (!accept_callback_.is_null()) { |
348 AcceptCompleted(); | 347 AcceptCompleted(); |
349 } else { // !read_callback_.is_null() | 348 } else { // !read_callback_.is_null() |
350 ReadCompleted(); | 349 ReadCompleted(); |
351 } | 350 } |
352 } | 351 } |
353 | 352 |
354 void SocketLibevent::OnFileCanWriteWithoutBlocking(int fd) { | 353 void SocketPosix::OnFileCanWriteWithoutBlocking(int fd) { |
355 DCHECK(!write_callback_.is_null()); | 354 DCHECK(!write_callback_.is_null()); |
356 if (waiting_connect_) { | 355 if (waiting_connect_) { |
357 ConnectCompleted(); | 356 ConnectCompleted(); |
358 } else { | 357 } else { |
359 WriteCompleted(); | 358 WriteCompleted(); |
360 } | 359 } |
361 } | 360 } |
362 | 361 |
363 int SocketLibevent::DoAccept(scoped_ptr<SocketLibevent>* socket) { | 362 int SocketPosix::DoAccept(scoped_ptr<SocketPosix>* socket) { |
364 SockaddrStorage new_peer_address; | 363 SockaddrStorage new_peer_address; |
365 int new_socket = HANDLE_EINTR(accept(socket_fd_, | 364 int new_socket = HANDLE_EINTR(accept(socket_fd_, |
366 new_peer_address.addr, | 365 new_peer_address.addr, |
367 &new_peer_address.addr_len)); | 366 &new_peer_address.addr_len)); |
368 if (new_socket < 0) | 367 if (new_socket < 0) |
369 return MapAcceptError(errno); | 368 return MapAcceptError(errno); |
370 | 369 |
371 scoped_ptr<SocketLibevent> accepted_socket(new SocketLibevent); | 370 scoped_ptr<SocketPosix> accepted_socket(new SocketPosix); |
372 int rv = accepted_socket->AdoptConnectedSocket(new_socket, new_peer_address); | 371 int rv = accepted_socket->AdoptConnectedSocket(new_socket, new_peer_address); |
373 if (rv != OK) | 372 if (rv != OK) |
374 return rv; | 373 return rv; |
375 | 374 |
376 *socket = accepted_socket.Pass(); | 375 *socket = accepted_socket.Pass(); |
377 return OK; | 376 return OK; |
378 } | 377 } |
379 | 378 |
380 void SocketLibevent::AcceptCompleted() { | 379 void SocketPosix::AcceptCompleted() { |
381 DCHECK(accept_socket_); | 380 DCHECK(accept_socket_); |
382 int rv = DoAccept(accept_socket_); | 381 int rv = DoAccept(accept_socket_); |
383 if (rv == ERR_IO_PENDING) | 382 if (rv == ERR_IO_PENDING) |
384 return; | 383 return; |
385 | 384 |
386 bool ok = accept_socket_watcher_.StopWatchingFileDescriptor(); | 385 bool ok = accept_socket_watcher_.StopWatchingFileDescriptor(); |
387 DCHECK(ok); | 386 DCHECK(ok); |
388 accept_socket_ = NULL; | 387 accept_socket_ = NULL; |
389 base::ResetAndReturn(&accept_callback_).Run(rv); | 388 base::ResetAndReturn(&accept_callback_).Run(rv); |
390 } | 389 } |
391 | 390 |
392 int SocketLibevent::DoConnect() { | 391 int SocketPosix::DoConnect() { |
393 int rv = HANDLE_EINTR(connect(socket_fd_, | 392 int rv = HANDLE_EINTR(connect(socket_fd_, |
394 peer_address_->addr, | 393 peer_address_->addr, |
395 peer_address_->addr_len)); | 394 peer_address_->addr_len)); |
396 DCHECK_GE(0, rv); | 395 DCHECK_GE(0, rv); |
397 return rv == 0 ? OK : MapConnectError(errno); | 396 return rv == 0 ? OK : MapConnectError(errno); |
398 } | 397 } |
399 | 398 |
400 void SocketLibevent::ConnectCompleted() { | 399 void SocketPosix::ConnectCompleted() { |
401 // Get the error that connect() completed with. | 400 // Get the error that connect() completed with. |
402 int os_error = 0; | 401 int os_error = 0; |
403 socklen_t len = sizeof(os_error); | 402 socklen_t len = sizeof(os_error); |
404 if (getsockopt(socket_fd_, SOL_SOCKET, SO_ERROR, &os_error, &len) == 0) { | 403 if (getsockopt(socket_fd_, SOL_SOCKET, SO_ERROR, &os_error, &len) == 0) { |
405 // TCPSocketLibevent expects errno to be set. | 404 // TCPSocketPosix expects errno to be set. |
406 errno = os_error; | 405 errno = os_error; |
407 } | 406 } |
408 | 407 |
409 int rv = MapConnectError(errno); | 408 int rv = MapConnectError(errno); |
410 if (rv == ERR_IO_PENDING) | 409 if (rv == ERR_IO_PENDING) |
411 return; | 410 return; |
412 | 411 |
413 bool ok = write_socket_watcher_.StopWatchingFileDescriptor(); | 412 bool ok = write_socket_watcher_.StopWatchingFileDescriptor(); |
414 DCHECK(ok); | 413 DCHECK(ok); |
415 waiting_connect_ = false; | 414 waiting_connect_ = false; |
416 base::ResetAndReturn(&write_callback_).Run(rv); | 415 base::ResetAndReturn(&write_callback_).Run(rv); |
417 } | 416 } |
418 | 417 |
419 int SocketLibevent::DoRead(IOBuffer* buf, int buf_len) { | 418 int SocketPosix::DoRead(IOBuffer* buf, int buf_len) { |
420 int rv = HANDLE_EINTR(read(socket_fd_, buf->data(), buf_len)); | 419 int rv = HANDLE_EINTR(read(socket_fd_, buf->data(), buf_len)); |
421 return rv >= 0 ? rv : MapSystemError(errno); | 420 return rv >= 0 ? rv : MapSystemError(errno); |
422 } | 421 } |
423 | 422 |
424 void SocketLibevent::ReadCompleted() { | 423 void SocketPosix::ReadCompleted() { |
425 int rv = DoRead(read_buf_.get(), read_buf_len_); | 424 int rv = DoRead(read_buf_.get(), read_buf_len_); |
426 if (rv == ERR_IO_PENDING) | 425 if (rv == ERR_IO_PENDING) |
427 return; | 426 return; |
428 | 427 |
429 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); | 428 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); |
430 DCHECK(ok); | 429 DCHECK(ok); |
431 read_buf_ = NULL; | 430 read_buf_ = NULL; |
432 read_buf_len_ = 0; | 431 read_buf_len_ = 0; |
433 base::ResetAndReturn(&read_callback_).Run(rv); | 432 base::ResetAndReturn(&read_callback_).Run(rv); |
434 } | 433 } |
435 | 434 |
436 int SocketLibevent::DoWrite(IOBuffer* buf, int buf_len) { | 435 int SocketPosix::DoWrite(IOBuffer* buf, int buf_len) { |
437 int rv = HANDLE_EINTR(write(socket_fd_, buf->data(), buf_len)); | 436 int rv = HANDLE_EINTR(write(socket_fd_, buf->data(), buf_len)); |
438 return rv >= 0 ? rv : MapSystemError(errno); | 437 return rv >= 0 ? rv : MapSystemError(errno); |
439 } | 438 } |
440 | 439 |
441 void SocketLibevent::WriteCompleted() { | 440 void SocketPosix::WriteCompleted() { |
442 int rv = DoWrite(write_buf_.get(), write_buf_len_); | 441 int rv = DoWrite(write_buf_.get(), write_buf_len_); |
443 if (rv == ERR_IO_PENDING) | 442 if (rv == ERR_IO_PENDING) |
444 return; | 443 return; |
445 | 444 |
446 bool ok = write_socket_watcher_.StopWatchingFileDescriptor(); | 445 bool ok = write_socket_watcher_.StopWatchingFileDescriptor(); |
447 DCHECK(ok); | 446 DCHECK(ok); |
448 write_buf_ = NULL; | 447 write_buf_ = NULL; |
449 write_buf_len_ = 0; | 448 write_buf_len_ = 0; |
450 base::ResetAndReturn(&write_callback_).Run(rv); | 449 base::ResetAndReturn(&write_callback_).Run(rv); |
451 } | 450 } |
452 | 451 |
453 void SocketLibevent::StopWatchingAndCleanUp() { | 452 void SocketPosix::StopWatchingAndCleanUp() { |
454 bool ok = accept_socket_watcher_.StopWatchingFileDescriptor(); | 453 bool ok = accept_socket_watcher_.StopWatchingFileDescriptor(); |
455 DCHECK(ok); | 454 DCHECK(ok); |
456 ok = read_socket_watcher_.StopWatchingFileDescriptor(); | 455 ok = read_socket_watcher_.StopWatchingFileDescriptor(); |
457 DCHECK(ok); | 456 DCHECK(ok); |
458 ok = write_socket_watcher_.StopWatchingFileDescriptor(); | 457 ok = write_socket_watcher_.StopWatchingFileDescriptor(); |
459 DCHECK(ok); | 458 DCHECK(ok); |
460 | 459 |
461 if (!accept_callback_.is_null()) { | 460 if (!accept_callback_.is_null()) { |
462 accept_socket_ = NULL; | 461 accept_socket_ = NULL; |
463 accept_callback_.Reset(); | 462 accept_callback_.Reset(); |
464 } | 463 } |
465 | 464 |
466 if (!read_callback_.is_null()) { | 465 if (!read_callback_.is_null()) { |
467 read_buf_ = NULL; | 466 read_buf_ = NULL; |
468 read_buf_len_ = 0; | 467 read_buf_len_ = 0; |
469 read_callback_.Reset(); | 468 read_callback_.Reset(); |
470 } | 469 } |
471 | 470 |
472 if (!write_callback_.is_null()) { | 471 if (!write_callback_.is_null()) { |
473 write_buf_ = NULL; | 472 write_buf_ = NULL; |
474 write_buf_len_ = 0; | 473 write_buf_len_ = 0; |
475 write_callback_.Reset(); | 474 write_callback_.Reset(); |
476 } | 475 } |
477 | 476 |
478 waiting_connect_ = false; | 477 waiting_connect_ = false; |
479 peer_address_.reset(); | 478 peer_address_.reset(); |
480 } | 479 } |
481 | 480 |
482 } // namespace net | 481 } // namespace net |
OLD | NEW |