| 566 | } |
| 567 | |
| 568 | int Socket::ResetFileDescriptor(int fd) { |
| 569 | // Reset message sizes when fd is changed. |
| 570 | _last_msg_size = 0; |
| 571 | _avg_msg_size = 0; |
| 572 | // MUST store `_fd' before adding itself into epoll device to avoid |
| 573 | // race conditions with the callback function inside epoll |
| 574 | _fd.store(fd, butil::memory_order_release); |
| 575 | _reset_fd_real_us = butil::cpuwide_time_us(); |
| 576 | if (!ValidFileDescriptor(fd)) { |
| 577 | return 0; |
| 578 | } |
| 579 | if (_remote_side == butil::EndPoint()) { |
| 580 | // OK to fail, non-socket fd does not support this. |
| 581 | butil::get_remote_side(fd, &_remote_side); |
| 582 | } |
| 583 | // OK to fail, non-socket fd does not support this. |
| 584 | butil::get_local_side(fd, &_local_side); |
| 585 | |
| 586 | // FIXME : close-on-exec should be set by new syscalls or worse: set right |
| 587 | // after fd-creation syscall. Setting at here has higher probabilities of |
| 588 | // race condition. |
| 589 | butil::make_close_on_exec(fd); |
| 590 | |
| 591 | // Make the fd non-blocking. |
| 592 | if (butil::make_non_blocking(fd) != 0) { |
| 593 | PLOG(ERROR) << "Fail to set fd=" << fd << " to non-blocking"; |
| 594 | _fd.store(-1, butil::memory_order_release); |
| 595 | return -1; |
| 596 | } |
| 597 | // turn off nagling. |
| 598 | // OK to fail, namely unix domain socket does not support this. |
| 599 | butil::make_no_delay(fd); |
| 600 | |
| 601 | SetSocketOptions(fd); |
| 602 | |
| 603 | if (_transport->HasOnEdgeTrigger()) { |
| 604 | if (_io_event.AddConsumer(fd) != 0) { |
| 605 | PLOG(ERROR) << "Fail to add SocketId=" << id() |
| 606 | << " into EventDispatcher"; |
| 607 | _fd.store(-1, butil::memory_order_release); |
| 608 | return -1; |
| 609 | } |
| 610 | } |
| 611 | return 0; |
| 612 | } |
| 613 | |
| 614 | void Socket::SetSocketOptions(int fd) { |
| 615 | if (_tos > 0 && |
no test coverage detected