Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 55 } | 55 } |
| 56 } | 56 } |
| 57 } | 57 } |
| 58 | 58 |
| 59 } // namespace | 59 } // namespace |
| 60 | 60 |
| 61 SocketPosix::SocketPosix() | 61 SocketPosix::SocketPosix() |
| 62 : socket_fd_(kInvalidSocket), | 62 : socket_fd_(kInvalidSocket), |
| 63 read_buf_len_(0), | 63 read_buf_len_(0), |
| 64 write_buf_len_(0), | 64 write_buf_len_(0), |
| 65 waiting_connect_(false) {} | 65 waiting_connect_(false), |
| 66 weak_factory_(this) {} | |
| 66 | 67 |
| 67 SocketPosix::~SocketPosix() { | 68 SocketPosix::~SocketPosix() { |
| 68 Close(); | 69 Close(); |
| 69 } | 70 } |
| 70 | 71 |
| 71 int SocketPosix::Open(int address_family) { | 72 int SocketPosix::Open(int address_family) { |
| 72 DCHECK(thread_checker_.CalledOnValidThread()); | 73 DCHECK(thread_checker_.CalledOnValidThread()); |
| 73 DCHECK_EQ(kInvalidSocket, socket_fd_); | 74 DCHECK_EQ(kInvalidSocket, socket_fd_); |
| 74 DCHECK(address_family == AF_INET || | 75 DCHECK(address_family == AF_INET || |
| 75 address_family == AF_INET6 || | 76 address_family == AF_INET6 || |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 243 return false; | 244 return false; |
| 244 if (errno != EAGAIN && errno != EWOULDBLOCK) | 245 if (errno != EAGAIN && errno != EWOULDBLOCK) |
| 245 return false; | 246 return false; |
| 246 | 247 |
| 247 return true; | 248 return true; |
| 248 } | 249 } |
| 249 | 250 |
| 250 int SocketPosix::Read(IOBuffer* buf, | 251 int SocketPosix::Read(IOBuffer* buf, |
| 251 int buf_len, | 252 int buf_len, |
| 252 const CompletionCallback& callback) { | 253 const CompletionCallback& callback) { |
| 254 int rv = ReadIfReady(buf, buf_len, base::Bind(&SocketPosix::RetryRead, | |
| 255 weak_factory_.GetWeakPtr())); | |
|
davidben
2017/02/10 23:33:48
Do you need a WeakPtr here? Since the callback won
xunjieli
2017/02/13 20:28:18
Done. You are right. I confused this one with the
| |
| 256 if (rv == ERR_IO_PENDING) { | |
| 257 read_buf_ = buf; | |
| 258 read_buf_len_ = buf_len; | |
| 259 read_callback_ = callback; | |
| 260 } | |
| 261 return rv; | |
| 262 } | |
| 263 | |
| 264 int SocketPosix::ReadIfReady(IOBuffer* buf, | |
| 265 int buf_len, | |
| 266 const CompletionCallback& callback) { | |
| 253 DCHECK(thread_checker_.CalledOnValidThread()); | 267 DCHECK(thread_checker_.CalledOnValidThread()); |
| 254 DCHECK_NE(kInvalidSocket, socket_fd_); | 268 DCHECK_NE(kInvalidSocket, socket_fd_); |
| 255 DCHECK(!waiting_connect_); | 269 DCHECK(!waiting_connect_); |
| 256 CHECK(read_callback_.is_null()); | 270 CHECK(read_if_ready_callback_.is_null()); |
| 257 // Synchronous operation not supported | 271 // Synchronous operation not supported |
| 258 DCHECK(!callback.is_null()); | 272 DCHECK(!callback.is_null()); |
| 259 DCHECK_LT(0, buf_len); | 273 DCHECK_LT(0, buf_len); |
| 260 | 274 |
| 261 int rv = DoRead(buf, buf_len); | 275 int rv = DoRead(buf, buf_len); |
| 262 if (rv != ERR_IO_PENDING) | 276 if (rv != ERR_IO_PENDING) |
| 263 return rv; | 277 return rv; |
| 264 | 278 |
| 265 if (!base::MessageLoopForIO::current()->WatchFileDescriptor( | 279 if (!base::MessageLoopForIO::current()->WatchFileDescriptor( |
| 266 socket_fd_, true, base::MessageLoopForIO::WATCH_READ, | 280 socket_fd_, true, base::MessageLoopForIO::WATCH_READ, |
| 267 &read_socket_watcher_, this)) { | 281 &read_socket_watcher_, this)) { |
| 268 PLOG(ERROR) << "WatchFileDescriptor failed on read, errno " << errno; | 282 PLOG(ERROR) << "WatchFileDescriptor failed on read, errno " << errno; |
| 269 return MapSystemError(errno); | 283 return MapSystemError(errno); |
| 270 } | 284 } |
| 271 | 285 |
| 272 read_buf_ = buf; | 286 read_if_ready_callback_ = callback; |
| 273 read_buf_len_ = buf_len; | |
| 274 read_callback_ = callback; | |
| 275 return ERR_IO_PENDING; | 287 return ERR_IO_PENDING; |
| 276 } | 288 } |
| 277 | 289 |
| 278 int SocketPosix::Write(IOBuffer* buf, | 290 int SocketPosix::Write(IOBuffer* buf, |
| 279 int buf_len, | 291 int buf_len, |
| 280 const CompletionCallback& callback) { | 292 const CompletionCallback& callback) { |
| 281 DCHECK(thread_checker_.CalledOnValidThread()); | 293 DCHECK(thread_checker_.CalledOnValidThread()); |
| 282 DCHECK_NE(kInvalidSocket, socket_fd_); | 294 DCHECK_NE(kInvalidSocket, socket_fd_); |
| 283 DCHECK(!waiting_connect_); | 295 DCHECK(!waiting_connect_); |
| 284 CHECK(write_callback_.is_null()); | 296 CHECK(write_callback_.is_null()); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 365 } | 377 } |
| 366 } | 378 } |
| 367 | 379 |
| 368 void SocketPosix::DetachFromThread() { | 380 void SocketPosix::DetachFromThread() { |
| 369 thread_checker_.DetachFromThread(); | 381 thread_checker_.DetachFromThread(); |
| 370 } | 382 } |
| 371 | 383 |
| 372 void SocketPosix::OnFileCanReadWithoutBlocking(int fd) { | 384 void SocketPosix::OnFileCanReadWithoutBlocking(int fd) { |
| 373 TRACE_EVENT0(kNetTracingCategory, | 385 TRACE_EVENT0(kNetTracingCategory, |
| 374 "SocketPosix::OnFileCanReadWithoutBlocking"); | 386 "SocketPosix::OnFileCanReadWithoutBlocking"); |
| 375 DCHECK(!accept_callback_.is_null() || !read_callback_.is_null()); | 387 DCHECK(!accept_callback_.is_null() || !read_if_ready_callback_.is_null()); |
| 376 if (!accept_callback_.is_null()) { | 388 if (!accept_callback_.is_null()) { |
| 377 AcceptCompleted(); | 389 AcceptCompleted(); |
| 378 } else { // !read_callback_.is_null() | 390 } else { // !read_if_ready_callback_.is_null() |
| 379 ReadCompleted(); | 391 ReadCompleted(); |
| 380 } | 392 } |
| 381 } | 393 } |
| 382 | 394 |
| 383 void SocketPosix::OnFileCanWriteWithoutBlocking(int fd) { | 395 void SocketPosix::OnFileCanWriteWithoutBlocking(int fd) { |
| 384 DCHECK(!write_callback_.is_null()); | 396 DCHECK(!write_callback_.is_null()); |
| 385 if (waiting_connect_) { | 397 if (waiting_connect_) { |
| 386 ConnectCompleted(); | 398 ConnectCompleted(); |
| 387 } else { | 399 } else { |
| 388 WriteCompleted(); | 400 WriteCompleted(); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 443 DCHECK(ok); | 455 DCHECK(ok); |
| 444 waiting_connect_ = false; | 456 waiting_connect_ = false; |
| 445 base::ResetAndReturn(&write_callback_).Run(rv); | 457 base::ResetAndReturn(&write_callback_).Run(rv); |
| 446 } | 458 } |
| 447 | 459 |
| 448 int SocketPosix::DoRead(IOBuffer* buf, int buf_len) { | 460 int SocketPosix::DoRead(IOBuffer* buf, int buf_len) { |
| 449 int rv = HANDLE_EINTR(read(socket_fd_, buf->data(), buf_len)); | 461 int rv = HANDLE_EINTR(read(socket_fd_, buf->data(), buf_len)); |
| 450 return rv >= 0 ? rv : MapSystemError(errno); | 462 return rv >= 0 ? rv : MapSystemError(errno); |
| 451 } | 463 } |
| 452 | 464 |
| 453 void SocketPosix::ReadCompleted() { | 465 void SocketPosix::RetryRead(int rv) { |
| 454 int rv = DoRead(read_buf_.get(), read_buf_len_); | 466 DCHECK(read_callback_); |
| 455 if (rv == ERR_IO_PENDING) | 467 DCHECK(read_buf_); |
| 456 return; | 468 DCHECK_LT(0, read_buf_len_); |
| 457 | 469 |
| 458 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); | 470 if (rv == OK) { |
| 459 DCHECK(ok); | 471 rv = ReadIfReady( |
| 460 read_buf_ = NULL; | 472 read_buf_.get(), read_buf_len_, |
| 473 base::Bind(&SocketPosix::RetryRead, weak_factory_.GetWeakPtr())); | |
| 474 if (rv == ERR_IO_PENDING) | |
| 475 return; | |
| 476 } | |
| 477 read_buf_ = nullptr; | |
| 461 read_buf_len_ = 0; | 478 read_buf_len_ = 0; |
| 462 base::ResetAndReturn(&read_callback_).Run(rv); | 479 base::ResetAndReturn(&read_callback_).Run(rv); |
| 463 } | 480 } |
| 464 | 481 |
| 482 void SocketPosix::ReadCompleted() { | |
| 483 DCHECK(read_if_ready_callback_); | |
| 484 | |
| 485 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); | |
| 486 DCHECK(ok); | |
| 487 base::ResetAndReturn(&read_if_ready_callback_).Run(OK); | |
| 488 } | |
| 489 | |
| 465 int SocketPosix::DoWrite(IOBuffer* buf, int buf_len) { | 490 int SocketPosix::DoWrite(IOBuffer* buf, int buf_len) { |
| 466 #if defined(OS_LINUX) || defined(OS_ANDROID) | 491 #if defined(OS_LINUX) || defined(OS_ANDROID) |
| 467 // Disable SIGPIPE for this write. Although Chromium globally disables | 492 // Disable SIGPIPE for this write. Although Chromium globally disables |
| 468 // SIGPIPE, the net stack may be used in other consumers which do not do | 493 // 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 | 494 // this. MSG_NOSIGNAL is a Linux-only API. On OS X, this is a setsockopt on |
| 470 // socket creation. | 495 // socket creation. |
| 471 int rv = HANDLE_EINTR(send(socket_fd_, buf->data(), buf_len, MSG_NOSIGNAL)); | 496 int rv = HANDLE_EINTR(send(socket_fd_, buf->data(), buf_len, MSG_NOSIGNAL)); |
| 472 #else | 497 #else |
| 473 int rv = HANDLE_EINTR(write(socket_fd_, buf->data(), buf_len)); | 498 int rv = HANDLE_EINTR(write(socket_fd_, buf->data(), buf_len)); |
| 474 #endif | 499 #endif |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 510 write_buf_ = NULL; | 535 write_buf_ = NULL; |
| 511 write_buf_len_ = 0; | 536 write_buf_len_ = 0; |
| 512 write_callback_.Reset(); | 537 write_callback_.Reset(); |
| 513 } | 538 } |
| 514 | 539 |
| 515 waiting_connect_ = false; | 540 waiting_connect_ = false; |
| 516 peer_address_.reset(); | 541 peer_address_.reset(); |
| 517 } | 542 } |
| 518 | 543 |
| 519 } // namespace net | 544 } // namespace net |
| OLD | NEW |