MCPcopy Create free account
hub / github.com/apache/thrift / read

Method read

lib/cpp/src/thrift/transport/TSocket.cpp:522–644  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

520}
521
522uint32_t TSocket::read(uint8_t* buf, uint32_t len) {
523 checkReadBytesAvailable(len);
524 if (socket_ == THRIFT_INVALID_SOCKET) {
525 throw TTransportException(TTransportException::NOT_OPEN, "Called read on non-open socket");
526 }
527
528 int32_t retries = 0;
529
530 // THRIFT_EAGAIN can be signalled both when a timeout has occurred and when
531 // the system is out of resources (an awesome undocumented feature).
532 // The following is an approximation of the time interval under which
533 // THRIFT_EAGAIN is taken to indicate an out of resources error.
534 uint32_t eagainThresholdMicros = 0;
535 if (recvTimeout_) {
536 // if a readTimeout is specified along with a max number of recv retries, then
537 // the threshold will ensure that the read timeout is not exceeded even in the
538 // case of resource errors
539 eagainThresholdMicros = (recvTimeout_ * 1000) / ((maxRecvRetries_ > 0) ? maxRecvRetries_ : 2);
540 }
541
542try_again:
543 // Read from the socket
544 struct timeval begin;
545 if (recvTimeout_ > 0) {
546 THRIFT_GETTIMEOFDAY(&begin, nullptr);
547 } else {
548 // if there is no read timeout we don't need the TOD to determine whether
549 // an THRIFT_EAGAIN is due to a timeout or an out-of-resource condition.
550 begin.tv_sec = begin.tv_usec = 0;
551 }
552
553 int got = 0;
554
555 if (interruptListener_) {
556 struct THRIFT_POLLFD fds[2];
557 std::memset(fds, 0, sizeof(fds));
558 fds[0].fd = socket_;
559 fds[0].events = THRIFT_POLLIN;
560 fds[1].fd = *(interruptListener_.get());
561 fds[1].events = THRIFT_POLLIN;
562
563 int ret = THRIFT_POLL(fds, 2, (recvTimeout_ == 0) ? -1 : recvTimeout_);
564 int errno_copy = THRIFT_GET_SOCKET_ERROR;
565 if (ret < 0) {
566 // error cases
567 if (errno_copy == THRIFT_EINTR && (retries++ < maxRecvRetries_)) {
568 goto try_again;
569 }
570 TOutput::instance().perror("TSocket::read() THRIFT_POLL() ", errno_copy);
571 throw TTransportException(TTransportException::UNKNOWN, "Unknown", errno_copy);
572 } else if (ret > 0) {
573 // Check the interruptListener
574 if (fds[1].revents & THRIFT_POLLIN) {
575 throw TTransportException(TTransportException::INTERRUPTED, "Interrupted");
576 }
577 } else /* ret == 0 */ {
578 TOutput::instance().printf("TSocket::read() THRIFT_EAGAIN (timed out) after %d ms", recvTimeout_);
579 throw TTransportException(TTransportException::TIMED_OUT, "THRIFT_EAGAIN (timed out)");

Callers

nothing calls this directly

Calls 5

printfMethod · 0.80
TTransportExceptionClass · 0.70
cast_sockoptFunction · 0.70
getMethod · 0.45
perrorMethod · 0.45

Tested by

no test coverage detected