| 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 |