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 |