| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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/base/tcp_client_socket_libevent.h" | 5 #include "net/base/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> |
| 11 | 11 |
| 12 #include "base/eintr_wrappers.h" |
| 12 #include "base/message_loop.h" | 13 #include "base/message_loop.h" |
| 13 #include "base/string_util.h" | 14 #include "base/string_util.h" |
| 14 #include "base/trace_event.h" | 15 #include "base/trace_event.h" |
| 15 #include "net/base/net_errors.h" | 16 #include "net/base/net_errors.h" |
| 16 #include "third_party/libevent/event.h" | 17 #include "third_party/libevent/event.h" |
| 17 | 18 |
| 18 | 19 |
| 19 namespace net { | 20 namespace net { |
| 20 | 21 |
| 21 const int kInvalidSocket = -1; | 22 const int kInvalidSocket = -1; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 DCHECK(!waiting_connect_); | 87 DCHECK(!waiting_connect_); |
| 87 | 88 |
| 88 TRACE_EVENT_BEGIN("socket.connect", this, ""); | 89 TRACE_EVENT_BEGIN("socket.connect", this, ""); |
| 89 const addrinfo* ai = current_ai_; | 90 const addrinfo* ai = current_ai_; |
| 90 DCHECK(ai); | 91 DCHECK(ai); |
| 91 | 92 |
| 92 int rv = CreateSocket(ai); | 93 int rv = CreateSocket(ai); |
| 93 if (rv != OK) | 94 if (rv != OK) |
| 94 return rv; | 95 return rv; |
| 95 | 96 |
| 96 if (!connect(socket_, ai->ai_addr, static_cast<int>(ai->ai_addrlen))) { | 97 if (!HANDLE_EINTR(connect(socket_, ai->ai_addr, |
| 98 static_cast<int>(ai->ai_addrlen)))) { |
| 97 TRACE_EVENT_END("socket.connect", this, ""); | 99 TRACE_EVENT_END("socket.connect", this, ""); |
| 98 // Connected without waiting! | 100 // Connected without waiting! |
| 99 return OK; | 101 return OK; |
| 100 } | 102 } |
| 101 | 103 |
| 102 // Synchronous operation not supported | 104 // Synchronous operation not supported |
| 103 DCHECK(callback); | 105 DCHECK(callback); |
| 104 | 106 |
| 105 if (errno != EINPROGRESS) { | 107 if (errno != EINPROGRESS) { |
| 106 DLOG(INFO) << "connect failed: " << errno; | 108 DLOG(INFO) << "connect failed: " << errno; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 // Reset for next time. | 142 // Reset for next time. |
| 141 current_ai_ = addresses_.head(); | 143 current_ai_ = addresses_.head(); |
| 142 } | 144 } |
| 143 | 145 |
| 144 bool TCPClientSocketLibevent::IsConnected() const { | 146 bool TCPClientSocketLibevent::IsConnected() const { |
| 145 if (socket_ == kInvalidSocket || waiting_connect_) | 147 if (socket_ == kInvalidSocket || waiting_connect_) |
| 146 return false; | 148 return false; |
| 147 | 149 |
| 148 // Check if connection is alive. | 150 // Check if connection is alive. |
| 149 char c; | 151 char c; |
| 150 int rv = recv(socket_, &c, 1, MSG_PEEK); | 152 int rv = HANDLE_EINTR(recv(socket_, &c, 1, MSG_PEEK)); |
| 151 if (rv == 0) | 153 if (rv == 0) |
| 152 return false; | 154 return false; |
| 153 if (rv == -1 && errno != EAGAIN && errno != EWOULDBLOCK) | 155 if (rv == -1 && errno != EAGAIN && errno != EWOULDBLOCK) |
| 154 return false; | 156 return false; |
| 155 | 157 |
| 156 return true; | 158 return true; |
| 157 } | 159 } |
| 158 | 160 |
| 159 bool TCPClientSocketLibevent::IsConnectedAndIdle() const { | 161 bool TCPClientSocketLibevent::IsConnectedAndIdle() const { |
| 160 if (socket_ == kInvalidSocket || waiting_connect_) | 162 if (socket_ == kInvalidSocket || waiting_connect_) |
| 161 return false; | 163 return false; |
| 162 | 164 |
| 163 // Check if connection is alive and we haven't received any data | 165 // Check if connection is alive and we haven't received any data |
| 164 // unexpectedly. | 166 // unexpectedly. |
| 165 char c; | 167 char c; |
| 166 int rv = recv(socket_, &c, 1, MSG_PEEK); | 168 int rv = HANDLE_EINTR(recv(socket_, &c, 1, MSG_PEEK)); |
| 167 if (rv >= 0) | 169 if (rv >= 0) |
| 168 return false; | 170 return false; |
| 169 if (errno != EAGAIN && errno != EWOULDBLOCK) | 171 if (errno != EAGAIN && errno != EWOULDBLOCK) |
| 170 return false; | 172 return false; |
| 171 | 173 |
| 172 return true; | 174 return true; |
| 173 } | 175 } |
| 174 | 176 |
| 175 int TCPClientSocketLibevent::Read(IOBuffer* buf, | 177 int TCPClientSocketLibevent::Read(IOBuffer* buf, |
| 176 int buf_len, | 178 int buf_len, |
| 177 CompletionCallback* callback) { | 179 CompletionCallback* callback) { |
| 178 DCHECK_NE(kInvalidSocket, socket_); | 180 DCHECK_NE(kInvalidSocket, socket_); |
| 179 DCHECK(!waiting_connect_); | 181 DCHECK(!waiting_connect_); |
| 180 DCHECK(!read_callback_); | 182 DCHECK(!read_callback_); |
| 181 // Synchronous operation not supported | 183 // Synchronous operation not supported |
| 182 DCHECK(callback); | 184 DCHECK(callback); |
| 183 DCHECK_GT(buf_len, 0); | 185 DCHECK_GT(buf_len, 0); |
| 184 | 186 |
| 185 TRACE_EVENT_BEGIN("socket.read", this, ""); | 187 TRACE_EVENT_BEGIN("socket.read", this, ""); |
| 186 int nread = read(socket_, buf->data(), buf_len); | 188 int nread = HANDLE_EINTR(read(socket_, buf->data(), buf_len)); |
| 187 if (nread >= 0) { | 189 if (nread >= 0) { |
| 188 TRACE_EVENT_END("socket.read", this, StringPrintf("%d bytes", nread)); | 190 TRACE_EVENT_END("socket.read", this, StringPrintf("%d bytes", nread)); |
| 189 return nread; | 191 return nread; |
| 190 } | 192 } |
| 191 if (errno != EAGAIN && errno != EWOULDBLOCK) { | 193 if (errno != EAGAIN && errno != EWOULDBLOCK) { |
| 192 DLOG(INFO) << "read failed, errno " << errno; | 194 DLOG(INFO) << "read failed, errno " << errno; |
| 193 return MapPosixError(errno); | 195 return MapPosixError(errno); |
| 194 } | 196 } |
| 195 | 197 |
| 196 if (!MessageLoopForIO::current()->WatchFileDescriptor( | 198 if (!MessageLoopForIO::current()->WatchFileDescriptor( |
| (...skipping 13 matching lines...) Expand all Loading... |
| 210 int buf_len, | 212 int buf_len, |
| 211 CompletionCallback* callback) { | 213 CompletionCallback* callback) { |
| 212 DCHECK_NE(kInvalidSocket, socket_); | 214 DCHECK_NE(kInvalidSocket, socket_); |
| 213 DCHECK(!waiting_connect_); | 215 DCHECK(!waiting_connect_); |
| 214 DCHECK(!write_callback_); | 216 DCHECK(!write_callback_); |
| 215 // Synchronous operation not supported | 217 // Synchronous operation not supported |
| 216 DCHECK(callback); | 218 DCHECK(callback); |
| 217 DCHECK_GT(buf_len, 0); | 219 DCHECK_GT(buf_len, 0); |
| 218 | 220 |
| 219 TRACE_EVENT_BEGIN("socket.write", this, ""); | 221 TRACE_EVENT_BEGIN("socket.write", this, ""); |
| 220 int nwrite = write(socket_, buf->data(), buf_len); | 222 int nwrite = HANDLE_EINTR(write(socket_, buf->data(), buf_len)); |
| 221 if (nwrite >= 0) { | 223 if (nwrite >= 0) { |
| 222 TRACE_EVENT_END("socket.write", this, StringPrintf("%d bytes", nwrite)); | 224 TRACE_EVENT_END("socket.write", this, StringPrintf("%d bytes", nwrite)); |
| 223 return nwrite; | 225 return nwrite; |
| 224 } | 226 } |
| 225 if (errno != EAGAIN && errno != EWOULDBLOCK) | 227 if (errno != EAGAIN && errno != EWOULDBLOCK) |
| 226 return MapPosixError(errno); | 228 return MapPosixError(errno); |
| 227 | 229 |
| 228 if (!MessageLoopForIO::current()->WatchFileDescriptor( | 230 if (!MessageLoopForIO::current()->WatchFileDescriptor( |
| 229 socket_, true, MessageLoopForIO::WATCH_WRITE, | 231 socket_, true, MessageLoopForIO::WATCH_WRITE, |
| 230 &socket_watcher_, this)) { | 232 &socket_watcher_, this)) { |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 302 waiting_connect_ = false; | 304 waiting_connect_ = false; |
| 303 } | 305 } |
| 304 | 306 |
| 305 if (result != ERR_IO_PENDING) { | 307 if (result != ERR_IO_PENDING) { |
| 306 DoReadCallback(result); | 308 DoReadCallback(result); |
| 307 } | 309 } |
| 308 } | 310 } |
| 309 | 311 |
| 310 void TCPClientSocketLibevent::DidCompleteRead() { | 312 void TCPClientSocketLibevent::DidCompleteRead() { |
| 311 int bytes_transferred; | 313 int bytes_transferred; |
| 312 bytes_transferred = read(socket_, read_buf_->data(), read_buf_len_); | 314 bytes_transferred = HANDLE_EINTR(read(socket_, read_buf_->data(), |
| 315 read_buf_len_)); |
| 313 | 316 |
| 314 int result; | 317 int result; |
| 315 if (bytes_transferred >= 0) { | 318 if (bytes_transferred >= 0) { |
| 316 TRACE_EVENT_END("socket.read", this, | 319 TRACE_EVENT_END("socket.read", this, |
| 317 StringPrintf("%d bytes", bytes_transferred)); | 320 StringPrintf("%d bytes", bytes_transferred)); |
| 318 result = bytes_transferred; | 321 result = bytes_transferred; |
| 319 } else { | 322 } else { |
| 320 result = MapPosixError(errno); | 323 result = MapPosixError(errno); |
| 321 } | 324 } |
| 322 | 325 |
| 323 if (result != ERR_IO_PENDING) { | 326 if (result != ERR_IO_PENDING) { |
| 324 read_buf_ = NULL; | 327 read_buf_ = NULL; |
| 325 read_buf_len_ = 0; | 328 read_buf_len_ = 0; |
| 326 socket_watcher_.StopWatchingFileDescriptor(); | 329 socket_watcher_.StopWatchingFileDescriptor(); |
| 327 DoReadCallback(result); | 330 DoReadCallback(result); |
| 328 } | 331 } |
| 329 } | 332 } |
| 330 | 333 |
| 331 void TCPClientSocketLibevent::DidCompleteWrite() { | 334 void TCPClientSocketLibevent::DidCompleteWrite() { |
| 332 int bytes_transferred; | 335 int bytes_transferred; |
| 333 bytes_transferred = write(socket_, write_buf_->data(), write_buf_len_); | 336 bytes_transferred = HANDLE_EINTR(write(socket_, write_buf_->data(), |
| 337 write_buf_len_)); |
| 334 | 338 |
| 335 int result; | 339 int result; |
| 336 if (bytes_transferred >= 0) { | 340 if (bytes_transferred >= 0) { |
| 337 result = bytes_transferred; | 341 result = bytes_transferred; |
| 338 TRACE_EVENT_END("socket.write", this, | 342 TRACE_EVENT_END("socket.write", this, |
| 339 StringPrintf("%d bytes", bytes_transferred)); | 343 StringPrintf("%d bytes", bytes_transferred)); |
| 340 } else { | 344 } else { |
| 341 result = MapPosixError(errno); | 345 result = MapPosixError(errno); |
| 342 } | 346 } |
| 343 | 347 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 364 DidCompleteWrite(); | 368 DidCompleteWrite(); |
| 365 } | 369 } |
| 366 } | 370 } |
| 367 | 371 |
| 368 int TCPClientSocketLibevent::GetPeerName(struct sockaddr *name, | 372 int TCPClientSocketLibevent::GetPeerName(struct sockaddr *name, |
| 369 socklen_t *namelen) { | 373 socklen_t *namelen) { |
| 370 return ::getpeername(socket_, name, namelen); | 374 return ::getpeername(socket_, name, namelen); |
| 371 } | 375 } |
| 372 | 376 |
| 373 } // namespace net | 377 } // namespace net |
| OLD | NEW |