Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(573)

Side by Side Diff: net/base/tcp_client_socket_libevent.cc

Issue 100225: POSIX: Add a macro for handling EINTR. (Closed)
Patch Set: ... Created 11 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/base/listen_socket_unittest.cc ('k') | net/base/telnet_server.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « net/base/listen_socket_unittest.cc ('k') | net/base/telnet_server.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698