| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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_client_socket_libevent.h" | 5 #include "net/socket/tcp_client_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 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 write_callback_(NULL), | 137 write_callback_(NULL), |
| 138 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) { | 138 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) { |
| 139 } | 139 } |
| 140 | 140 |
| 141 TCPClientSocketLibevent::~TCPClientSocketLibevent() { | 141 TCPClientSocketLibevent::~TCPClientSocketLibevent() { |
| 142 Disconnect(); | 142 Disconnect(); |
| 143 net_log_.AddEvent(NetLog::TYPE_TCP_SOCKET_DONE, NULL); | 143 net_log_.AddEvent(NetLog::TYPE_TCP_SOCKET_DONE, NULL); |
| 144 } | 144 } |
| 145 | 145 |
| 146 int TCPClientSocketLibevent::Connect(CompletionCallback* callback) { | 146 int TCPClientSocketLibevent::Connect(CompletionCallback* callback) { |
| 147 DCHECK(CalledOnValidThread()); |
| 148 |
| 147 // If already connected, then just return OK. | 149 // If already connected, then just return OK. |
| 148 if (socket_ != kInvalidSocket) | 150 if (socket_ != kInvalidSocket) |
| 149 return OK; | 151 return OK; |
| 150 | 152 |
| 151 DCHECK(!waiting_connect_); | 153 DCHECK(!waiting_connect_); |
| 152 | 154 |
| 153 TRACE_EVENT_BEGIN("socket.connect", this, ""); | 155 TRACE_EVENT_BEGIN("socket.connect", this, ""); |
| 154 | 156 |
| 155 net_log_.BeginEvent(NetLog::TYPE_TCP_CONNECT, NULL); | 157 net_log_.BeginEvent(NetLog::TYPE_TCP_CONNECT, NULL); |
| 156 | 158 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 DLOG(INFO) << "WatchFileDescriptor failed: " << errno; | 213 DLOG(INFO) << "WatchFileDescriptor failed: " << errno; |
| 212 close(socket_); | 214 close(socket_); |
| 213 socket_ = kInvalidSocket; | 215 socket_ = kInvalidSocket; |
| 214 return MapPosixError(errno); | 216 return MapPosixError(errno); |
| 215 } | 217 } |
| 216 | 218 |
| 217 return ERR_IO_PENDING; | 219 return ERR_IO_PENDING; |
| 218 } | 220 } |
| 219 | 221 |
| 220 void TCPClientSocketLibevent::Disconnect() { | 222 void TCPClientSocketLibevent::Disconnect() { |
| 223 DCHECK(CalledOnValidThread()); |
| 224 |
| 221 if (socket_ == kInvalidSocket) | 225 if (socket_ == kInvalidSocket) |
| 222 return; | 226 return; |
| 223 | 227 |
| 224 TRACE_EVENT_INSTANT("socket.disconnect", this, ""); | 228 TRACE_EVENT_INSTANT("socket.disconnect", this, ""); |
| 225 | 229 |
| 226 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); | 230 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); |
| 227 DCHECK(ok); | 231 DCHECK(ok); |
| 228 ok = write_socket_watcher_.StopWatchingFileDescriptor(); | 232 ok = write_socket_watcher_.StopWatchingFileDescriptor(); |
| 229 DCHECK(ok); | 233 DCHECK(ok); |
| 230 close(socket_); | 234 close(socket_); |
| 231 socket_ = kInvalidSocket; | 235 socket_ = kInvalidSocket; |
| 232 waiting_connect_ = false; | 236 waiting_connect_ = false; |
| 233 | 237 |
| 234 // Reset for next time. | 238 // Reset for next time. |
| 235 current_ai_ = addresses_.head(); | 239 current_ai_ = addresses_.head(); |
| 236 } | 240 } |
| 237 | 241 |
| 238 bool TCPClientSocketLibevent::IsConnected() const { | 242 bool TCPClientSocketLibevent::IsConnected() const { |
| 243 DCHECK(CalledOnValidThread()); |
| 244 |
| 239 if (socket_ == kInvalidSocket || waiting_connect_) | 245 if (socket_ == kInvalidSocket || waiting_connect_) |
| 240 return false; | 246 return false; |
| 241 | 247 |
| 242 // Check if connection is alive. | 248 // Check if connection is alive. |
| 243 char c; | 249 char c; |
| 244 int rv = HANDLE_EINTR(recv(socket_, &c, 1, MSG_PEEK)); | 250 int rv = HANDLE_EINTR(recv(socket_, &c, 1, MSG_PEEK)); |
| 245 if (rv == 0) | 251 if (rv == 0) |
| 246 return false; | 252 return false; |
| 247 if (rv == -1 && errno != EAGAIN && errno != EWOULDBLOCK) | 253 if (rv == -1 && errno != EAGAIN && errno != EWOULDBLOCK) |
| 248 return false; | 254 return false; |
| 249 | 255 |
| 250 return true; | 256 return true; |
| 251 } | 257 } |
| 252 | 258 |
| 253 bool TCPClientSocketLibevent::IsConnectedAndIdle() const { | 259 bool TCPClientSocketLibevent::IsConnectedAndIdle() const { |
| 260 DCHECK(CalledOnValidThread()); |
| 261 |
| 254 if (socket_ == kInvalidSocket || waiting_connect_) | 262 if (socket_ == kInvalidSocket || waiting_connect_) |
| 255 return false; | 263 return false; |
| 256 | 264 |
| 257 // Check if connection is alive and we haven't received any data | 265 // Check if connection is alive and we haven't received any data |
| 258 // unexpectedly. | 266 // unexpectedly. |
| 259 char c; | 267 char c; |
| 260 int rv = HANDLE_EINTR(recv(socket_, &c, 1, MSG_PEEK)); | 268 int rv = HANDLE_EINTR(recv(socket_, &c, 1, MSG_PEEK)); |
| 261 if (rv >= 0) | 269 if (rv >= 0) |
| 262 return false; | 270 return false; |
| 263 if (errno != EAGAIN && errno != EWOULDBLOCK) | 271 if (errno != EAGAIN && errno != EWOULDBLOCK) |
| 264 return false; | 272 return false; |
| 265 | 273 |
| 266 return true; | 274 return true; |
| 267 } | 275 } |
| 268 | 276 |
| 269 int TCPClientSocketLibevent::Read(IOBuffer* buf, | 277 int TCPClientSocketLibevent::Read(IOBuffer* buf, |
| 270 int buf_len, | 278 int buf_len, |
| 271 CompletionCallback* callback) { | 279 CompletionCallback* callback) { |
| 280 DCHECK(CalledOnValidThread()); |
| 272 DCHECK_NE(kInvalidSocket, socket_); | 281 DCHECK_NE(kInvalidSocket, socket_); |
| 273 DCHECK(!waiting_connect_); | 282 DCHECK(!waiting_connect_); |
| 274 DCHECK(!read_callback_); | 283 DCHECK(!read_callback_); |
| 275 // Synchronous operation not supported | 284 // Synchronous operation not supported |
| 276 DCHECK(callback); | 285 DCHECK(callback); |
| 277 DCHECK_GT(buf_len, 0); | 286 DCHECK_GT(buf_len, 0); |
| 278 | 287 |
| 279 TRACE_EVENT_BEGIN("socket.read", this, ""); | 288 TRACE_EVENT_BEGIN("socket.read", this, ""); |
| 280 int nread = HANDLE_EINTR(read(socket_, buf->data(), buf_len)); | 289 int nread = HANDLE_EINTR(read(socket_, buf->data(), buf_len)); |
| 281 if (nread >= 0) { | 290 if (nread >= 0) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 298 | 307 |
| 299 read_buf_ = buf; | 308 read_buf_ = buf; |
| 300 read_buf_len_ = buf_len; | 309 read_buf_len_ = buf_len; |
| 301 read_callback_ = callback; | 310 read_callback_ = callback; |
| 302 return ERR_IO_PENDING; | 311 return ERR_IO_PENDING; |
| 303 } | 312 } |
| 304 | 313 |
| 305 int TCPClientSocketLibevent::Write(IOBuffer* buf, | 314 int TCPClientSocketLibevent::Write(IOBuffer* buf, |
| 306 int buf_len, | 315 int buf_len, |
| 307 CompletionCallback* callback) { | 316 CompletionCallback* callback) { |
| 317 DCHECK(CalledOnValidThread()); |
| 308 DCHECK_NE(kInvalidSocket, socket_); | 318 DCHECK_NE(kInvalidSocket, socket_); |
| 309 DCHECK(!waiting_connect_); | 319 DCHECK(!waiting_connect_); |
| 310 DCHECK(!write_callback_); | 320 DCHECK(!write_callback_); |
| 311 // Synchronous operation not supported | 321 // Synchronous operation not supported |
| 312 DCHECK(callback); | 322 DCHECK(callback); |
| 313 DCHECK_GT(buf_len, 0); | 323 DCHECK_GT(buf_len, 0); |
| 314 | 324 |
| 315 TRACE_EVENT_BEGIN("socket.write", this, ""); | 325 TRACE_EVENT_BEGIN("socket.write", this, ""); |
| 316 int nwrite = HANDLE_EINTR(write(socket_, buf->data(), buf_len)); | 326 int nwrite = HANDLE_EINTR(write(socket_, buf->data(), buf_len)); |
| 317 if (nwrite >= 0) { | 327 if (nwrite >= 0) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 331 } | 341 } |
| 332 | 342 |
| 333 | 343 |
| 334 write_buf_ = buf; | 344 write_buf_ = buf; |
| 335 write_buf_len_ = buf_len; | 345 write_buf_len_ = buf_len; |
| 336 write_callback_ = callback; | 346 write_callback_ = callback; |
| 337 return ERR_IO_PENDING; | 347 return ERR_IO_PENDING; |
| 338 } | 348 } |
| 339 | 349 |
| 340 bool TCPClientSocketLibevent::SetReceiveBufferSize(int32 size) { | 350 bool TCPClientSocketLibevent::SetReceiveBufferSize(int32 size) { |
| 351 DCHECK(CalledOnValidThread()); |
| 341 int rv = setsockopt(socket_, SOL_SOCKET, SO_RCVBUF, | 352 int rv = setsockopt(socket_, SOL_SOCKET, SO_RCVBUF, |
| 342 reinterpret_cast<const char*>(&size), | 353 reinterpret_cast<const char*>(&size), |
| 343 sizeof(size)); | 354 sizeof(size)); |
| 344 DCHECK(!rv) << "Could not set socket receive buffer size: " << errno; | 355 DCHECK(!rv) << "Could not set socket receive buffer size: " << errno; |
| 345 return rv == 0; | 356 return rv == 0; |
| 346 } | 357 } |
| 347 | 358 |
| 348 bool TCPClientSocketLibevent::SetSendBufferSize(int32 size) { | 359 bool TCPClientSocketLibevent::SetSendBufferSize(int32 size) { |
| 360 DCHECK(CalledOnValidThread()); |
| 349 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, | 361 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, |
| 350 reinterpret_cast<const char*>(&size), | 362 reinterpret_cast<const char*>(&size), |
| 351 sizeof(size)); | 363 sizeof(size)); |
| 352 DCHECK(!rv) << "Could not set socket send buffer size: " << errno; | 364 DCHECK(!rv) << "Could not set socket send buffer size: " << errno; |
| 353 return rv == 0; | 365 return rv == 0; |
| 354 } | 366 } |
| 355 | 367 |
| 356 | 368 |
| 357 int TCPClientSocketLibevent::CreateSocket(const addrinfo* ai) { | 369 int TCPClientSocketLibevent::CreateSocket(const addrinfo* ai) { |
| 358 socket_ = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); | 370 socket_ = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 470 | 482 |
| 471 if (result != ERR_IO_PENDING) { | 483 if (result != ERR_IO_PENDING) { |
| 472 write_buf_ = NULL; | 484 write_buf_ = NULL; |
| 473 write_buf_len_ = 0; | 485 write_buf_len_ = 0; |
| 474 write_socket_watcher_.StopWatchingFileDescriptor(); | 486 write_socket_watcher_.StopWatchingFileDescriptor(); |
| 475 DoWriteCallback(result); | 487 DoWriteCallback(result); |
| 476 } | 488 } |
| 477 } | 489 } |
| 478 | 490 |
| 479 int TCPClientSocketLibevent::GetPeerAddress(AddressList* address) const { | 491 int TCPClientSocketLibevent::GetPeerAddress(AddressList* address) const { |
| 492 DCHECK(CalledOnValidThread()); |
| 480 DCHECK(address); | 493 DCHECK(address); |
| 481 if (!current_ai_) | 494 if (!current_ai_) |
| 482 return ERR_UNEXPECTED; | 495 return ERR_UNEXPECTED; |
| 483 address->Copy(current_ai_, false); | 496 address->Copy(current_ai_, false); |
| 484 return OK; | 497 return OK; |
| 485 } | 498 } |
| 486 | 499 |
| 487 } // namespace net | 500 } // namespace net |
| OLD | NEW |