| 627 | } |
| 628 | |
| 629 | shared_ptr<TTransport> TServerSocket::acceptImpl() { |
| 630 | if (serverSocket_ == THRIFT_INVALID_SOCKET) { |
| 631 | throw TTransportException(TTransportException::NOT_OPEN, "TServerSocket not listening"); |
| 632 | } |
| 633 | |
| 634 | struct THRIFT_POLLFD fds[2]; |
| 635 | |
| 636 | int maxEintrs = 5; |
| 637 | int numEintrs = 0; |
| 638 | |
| 639 | while (true) { |
| 640 | std::memset(fds, 0, sizeof(fds)); |
| 641 | fds[0].fd = serverSocket_; |
| 642 | fds[0].events = THRIFT_POLLIN; |
| 643 | if (interruptSockReader_ != THRIFT_INVALID_SOCKET) { |
| 644 | fds[1].fd = interruptSockReader_; |
| 645 | fds[1].events = THRIFT_POLLIN; |
| 646 | } |
| 647 | /* |
| 648 | TODO: if THRIFT_EINTR is received, we'll restart the timeout. |
| 649 | To be accurate, we need to fix this in the future. |
| 650 | */ |
| 651 | int ret = THRIFT_POLL(fds, 2, accTimeout_); |
| 652 | |
| 653 | if (ret < 0) { |
| 654 | // error cases |
| 655 | if (THRIFT_GET_SOCKET_ERROR == THRIFT_EINTR && (numEintrs++ < maxEintrs)) { |
| 656 | // THRIFT_EINTR needs to be handled manually and we can tolerate |
| 657 | // a certain number |
| 658 | continue; |
| 659 | } |
| 660 | int errno_copy = THRIFT_GET_SOCKET_ERROR; |
| 661 | TOutput::instance().perror("TServerSocket::acceptImpl() THRIFT_POLL() ", errno_copy); |
| 662 | throw TTransportException(TTransportException::UNKNOWN, "Unknown", errno_copy); |
| 663 | } else if (ret > 0) { |
| 664 | // Check for an interrupt signal |
| 665 | if (interruptSockReader_ != THRIFT_INVALID_SOCKET && (fds[1].revents & THRIFT_POLLIN)) { |
| 666 | int8_t buf; |
| 667 | if (-1 == recv(interruptSockReader_, cast_sockopt(&buf), sizeof(int8_t), 0)) { |
| 668 | TOutput::instance().perror("TServerSocket::acceptImpl() recv() interrupt ", |
| 669 | THRIFT_GET_SOCKET_ERROR); |
| 670 | } |
| 671 | throw TTransportException(TTransportException::INTERRUPTED); |
| 672 | } |
| 673 | |
| 674 | // Check for the actual server socket being ready |
| 675 | if (fds[0].revents & THRIFT_POLLIN) { |
| 676 | break; |
| 677 | } |
| 678 | } else { |
| 679 | TOutput::instance()("TServerSocket::acceptImpl() THRIFT_POLL 0"); |
| 680 | throw TTransportException(TTransportException::UNKNOWN); |
| 681 | } |
| 682 | } |
| 683 | |
| 684 | struct sockaddr_storage clientAddress; |
| 685 | int size = sizeof(clientAddress); |
| 686 | THRIFT_SOCKET clientSocket |
nothing calls this directly
no test coverage detected