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

Side by Side Diff: net/socket/socket_posix.cc

Issue 2593063003: Add Socket::ReadIfReady() (Closed)
Patch Set: Fix perf tests (removed invalid CHECKs) Created 3 years, 10 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
OLDNEW
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_posix.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 #include <utility> 10 #include <utility>
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 return false; 243 return false;
244 if (errno != EAGAIN && errno != EWOULDBLOCK) 244 if (errno != EAGAIN && errno != EWOULDBLOCK)
245 return false; 245 return false;
246 246
247 return true; 247 return true;
248 } 248 }
249 249
250 int SocketPosix::Read(IOBuffer* buf, 250 int SocketPosix::Read(IOBuffer* buf,
251 int buf_len, 251 int buf_len,
252 const CompletionCallback& callback) { 252 const CompletionCallback& callback) {
253 // Use base::Unretained() is safe here because OnFileCanReadWithoutBlocking()
254 // won't be called if |this| is gone.
255 int rv = ReadIfReady(buf, buf_len, base::Bind(&SocketPosix::RetryRead,
256 base::Unretained(this)));
257 if (rv == ERR_IO_PENDING) {
258 read_buf_ = buf;
259 read_buf_len_ = buf_len;
260 read_callback_ = callback;
261 }
262 return rv;
263 }
264
265 int SocketPosix::ReadIfReady(IOBuffer* buf,
266 int buf_len,
267 const CompletionCallback& callback) {
253 DCHECK(thread_checker_.CalledOnValidThread()); 268 DCHECK(thread_checker_.CalledOnValidThread());
254 DCHECK_NE(kInvalidSocket, socket_fd_); 269 DCHECK_NE(kInvalidSocket, socket_fd_);
255 DCHECK(!waiting_connect_); 270 DCHECK(!waiting_connect_);
256 CHECK(read_callback_.is_null()); 271 CHECK(read_if_ready_callback_.is_null());
257 // Synchronous operation not supported 272 // Synchronous operation not supported
258 DCHECK(!callback.is_null()); 273 DCHECK(!callback.is_null());
259 DCHECK_LT(0, buf_len); 274 DCHECK_LT(0, buf_len);
260 275
261 int rv = DoRead(buf, buf_len); 276 int rv = DoRead(buf, buf_len);
262 if (rv != ERR_IO_PENDING) 277 if (rv != ERR_IO_PENDING)
263 return rv; 278 return rv;
264 279
265 if (!base::MessageLoopForIO::current()->WatchFileDescriptor( 280 if (!base::MessageLoopForIO::current()->WatchFileDescriptor(
266 socket_fd_, true, base::MessageLoopForIO::WATCH_READ, 281 socket_fd_, true, base::MessageLoopForIO::WATCH_READ,
267 &read_socket_watcher_, this)) { 282 &read_socket_watcher_, this)) {
268 PLOG(ERROR) << "WatchFileDescriptor failed on read, errno " << errno; 283 PLOG(ERROR) << "WatchFileDescriptor failed on read, errno " << errno;
269 return MapSystemError(errno); 284 return MapSystemError(errno);
270 } 285 }
271 286
272 read_buf_ = buf; 287 read_if_ready_callback_ = callback;
273 read_buf_len_ = buf_len;
274 read_callback_ = callback;
275 return ERR_IO_PENDING; 288 return ERR_IO_PENDING;
276 } 289 }
277 290
278 int SocketPosix::Write(IOBuffer* buf, 291 int SocketPosix::Write(IOBuffer* buf,
279 int buf_len, 292 int buf_len,
280 const CompletionCallback& callback) { 293 const CompletionCallback& callback) {
281 DCHECK(thread_checker_.CalledOnValidThread()); 294 DCHECK(thread_checker_.CalledOnValidThread());
282 DCHECK_NE(kInvalidSocket, socket_fd_); 295 DCHECK_NE(kInvalidSocket, socket_fd_);
283 DCHECK(!waiting_connect_); 296 DCHECK(!waiting_connect_);
284 CHECK(write_callback_.is_null()); 297 CHECK(write_callback_.is_null());
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 } 378 }
366 } 379 }
367 380
368 void SocketPosix::DetachFromThread() { 381 void SocketPosix::DetachFromThread() {
369 thread_checker_.DetachFromThread(); 382 thread_checker_.DetachFromThread();
370 } 383 }
371 384
372 void SocketPosix::OnFileCanReadWithoutBlocking(int fd) { 385 void SocketPosix::OnFileCanReadWithoutBlocking(int fd) {
373 TRACE_EVENT0(kNetTracingCategory, 386 TRACE_EVENT0(kNetTracingCategory,
374 "SocketPosix::OnFileCanReadWithoutBlocking"); 387 "SocketPosix::OnFileCanReadWithoutBlocking");
375 DCHECK(!accept_callback_.is_null() || !read_callback_.is_null()); 388 DCHECK(!accept_callback_.is_null() || !read_if_ready_callback_.is_null());
376 if (!accept_callback_.is_null()) { 389 if (!accept_callback_.is_null()) {
377 AcceptCompleted(); 390 AcceptCompleted();
378 } else { // !read_callback_.is_null() 391 } else { // !read_if_ready_callback_.is_null()
379 ReadCompleted(); 392 ReadCompleted();
380 } 393 }
381 } 394 }
382 395
383 void SocketPosix::OnFileCanWriteWithoutBlocking(int fd) { 396 void SocketPosix::OnFileCanWriteWithoutBlocking(int fd) {
384 DCHECK(!write_callback_.is_null()); 397 DCHECK(!write_callback_.is_null());
385 if (waiting_connect_) { 398 if (waiting_connect_) {
386 ConnectCompleted(); 399 ConnectCompleted();
387 } else { 400 } else {
388 WriteCompleted(); 401 WriteCompleted();
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 DCHECK(ok); 456 DCHECK(ok);
444 waiting_connect_ = false; 457 waiting_connect_ = false;
445 base::ResetAndReturn(&write_callback_).Run(rv); 458 base::ResetAndReturn(&write_callback_).Run(rv);
446 } 459 }
447 460
448 int SocketPosix::DoRead(IOBuffer* buf, int buf_len) { 461 int SocketPosix::DoRead(IOBuffer* buf, int buf_len) {
449 int rv = HANDLE_EINTR(read(socket_fd_, buf->data(), buf_len)); 462 int rv = HANDLE_EINTR(read(socket_fd_, buf->data(), buf_len));
450 return rv >= 0 ? rv : MapSystemError(errno); 463 return rv >= 0 ? rv : MapSystemError(errno);
451 } 464 }
452 465
453 void SocketPosix::ReadCompleted() { 466 void SocketPosix::RetryRead(int rv) {
454 int rv = DoRead(read_buf_.get(), read_buf_len_); 467 DCHECK(read_callback_);
455 if (rv == ERR_IO_PENDING) 468 DCHECK(read_buf_);
456 return; 469 DCHECK_LT(0, read_buf_len_);
457 470
458 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); 471 if (rv == OK) {
459 DCHECK(ok); 472 rv = ReadIfReady(
460 read_buf_ = NULL; 473 read_buf_.get(), read_buf_len_,
474 base::Bind(&SocketPosix::RetryRead, base::Unretained(this)));
475 if (rv == ERR_IO_PENDING)
476 return;
477 }
478 read_buf_ = nullptr;
461 read_buf_len_ = 0; 479 read_buf_len_ = 0;
462 base::ResetAndReturn(&read_callback_).Run(rv); 480 base::ResetAndReturn(&read_callback_).Run(rv);
463 } 481 }
464 482
483 void SocketPosix::ReadCompleted() {
484 DCHECK(read_if_ready_callback_);
485
486 bool ok = read_socket_watcher_.StopWatchingFileDescriptor();
487 DCHECK(ok);
488 base::ResetAndReturn(&read_if_ready_callback_).Run(OK);
489 }
490
465 int SocketPosix::DoWrite(IOBuffer* buf, int buf_len) { 491 int SocketPosix::DoWrite(IOBuffer* buf, int buf_len) {
466 #if defined(OS_LINUX) || defined(OS_ANDROID) 492 #if defined(OS_LINUX) || defined(OS_ANDROID)
467 // Disable SIGPIPE for this write. Although Chromium globally disables 493 // Disable SIGPIPE for this write. Although Chromium globally disables
468 // SIGPIPE, the net stack may be used in other consumers which do not do 494 // SIGPIPE, the net stack may be used in other consumers which do not do
469 // this. MSG_NOSIGNAL is a Linux-only API. On OS X, this is a setsockopt on 495 // this. MSG_NOSIGNAL is a Linux-only API. On OS X, this is a setsockopt on
470 // socket creation. 496 // socket creation.
471 int rv = HANDLE_EINTR(send(socket_fd_, buf->data(), buf_len, MSG_NOSIGNAL)); 497 int rv = HANDLE_EINTR(send(socket_fd_, buf->data(), buf_len, MSG_NOSIGNAL));
472 #else 498 #else
473 int rv = HANDLE_EINTR(write(socket_fd_, buf->data(), buf_len)); 499 int rv = HANDLE_EINTR(write(socket_fd_, buf->data(), buf_len));
474 #endif 500 #endif
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 write_buf_ = NULL; 536 write_buf_ = NULL;
511 write_buf_len_ = 0; 537 write_buf_len_ = 0;
512 write_callback_.Reset(); 538 write_callback_.Reset();
513 } 539 }
514 540
515 waiting_connect_ = false; 541 waiting_connect_ = false;
516 peer_address_.reset(); 542 peer_address_.reset();
517 } 543 }
518 544
519 } // namespace net 545 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698