in quic/api/QuicStreamAsyncTransport.cpp [371:436]
void QuicStreamAsyncTransport::handleRead() {
folly::DelayedDestruction::DestructorGuard dg(this);
bool emptyRead = false;
size_t numReads = 0;
while (readCb_ && id_ && !ex_ && readEOF_ == EOFState::NOT_SEEN &&
!emptyRead && ++numReads < 16 /* max reads per event */) {
void* buf = nullptr;
size_t len = 0;
if (readCb_->isBufferMovable()) {
len = readCb_->maxBufferSize();
} else {
readCb_->getReadBuffer(&buf, &len);
if (buf == nullptr || len == 0) {
ex_ = folly::AsyncSocketException(
folly::AsyncSocketException::BAD_ARGS,
"ReadCallback::getReadBuffer() returned empty buffer");
break;
}
}
auto readData = sock_->read(*id_, len);
if (readData.hasError()) {
ex_ = folly::AsyncSocketException(
folly::AsyncSocketException::UNKNOWN,
folly::to<std::string>("Quic read error: ", readData.error()));
} else {
if (!readData->first) {
emptyRead = true;
} else {
if (readCb_->isBufferMovable()) {
readCb_->readBufferAvailable(std::move(readData->first));
} else {
size_t readLen = readData->first->computeChainDataLength();
folly::io::Cursor c(readData->first.get());
CHECK_NOTNULL(buf);
c.pull(buf, readLen);
readCb_->readDataAvailable(readLen);
}
}
if (readData->second && readEOF_ == EOFState::NOT_SEEN) {
readEOF_ = EOFState::QUEUED;
}
}
}
// in case readCb_ got reset from read callbacks
if (!readCb_) {
return;
}
if (ex_) {
auto cb = readCb_;
readCb_ = nullptr;
cb->readErr(*ex_);
} else if (readEOF_ == EOFState::QUEUED) {
auto cb = readCb_;
readCb_ = nullptr;
cb->readEOF();
readEOF_ = EOFState::DELIVERED;
}
if (id_) {
if (!readCb_ || readEOF_ != EOFState::NOT_SEEN) {
sock_->setReadCallback(*id_, nullptr);
}
}
}