mirror of
https://github.com/facebookincubator/mvfst.git
synced 2025-08-08 09:42:06 +03:00
Move QuicEventBase and QuicTimer callback operations back to the Callbacks themselves.
Summary: This moves all the loop and timer callback operations back to the callbacks instead of relying the QuicEventBase to perform them. I.e. it's now Callback::cancelCallback() instead of QuicEventBase::cancelCallback(&callback). To simplify the design, the lifetime of LoopCallbackWrapper and TimerCallbackWrapper has been changed. Previously these wrappers lasted for one iteration of the loop or the timer callback. In the new design the wrapper is created the first time the callback is scheduled and is only destroyed when the callback is destroyed. This significantly simplifies the lifetime management of the wrapper and the code overall. While transitioning LibevQuicEventBase to this new design, this change also consolidates the QuicTimer functionality in the LibevQuicEventBase itself. Reviewed By: hanidamlaj, mjoras Differential Revision: D52217879 fbshipit-source-id: da7b95d592650ddc112813fdc3b9f5010d32e7fb
This commit is contained in:
committed by
Facebook GitHub Bot
parent
2008fa9163
commit
96b65104dc
@@ -86,11 +86,10 @@ bool IOBufQuicBatch::flushInternal() {
|
|||||||
// If error occurred on first socket, kick off second socket immediately
|
// If error occurred on first socket, kick off second socket immediately
|
||||||
if (!written && happyEyeballsState_ &&
|
if (!written && happyEyeballsState_ &&
|
||||||
happyEyeballsState_->connAttemptDelayTimeout &&
|
happyEyeballsState_->connAttemptDelayTimeout &&
|
||||||
sock_.getEventBase()->isTimeoutScheduled(
|
happyEyeballsState_->connAttemptDelayTimeout
|
||||||
happyEyeballsState_->connAttemptDelayTimeout)) {
|
->isTimerCallbackScheduled()) {
|
||||||
|
happyEyeballsState_->connAttemptDelayTimeout->cancelTimerCallback();
|
||||||
happyEyeballsState_->connAttemptDelayTimeout->timeoutExpired();
|
happyEyeballsState_->connAttemptDelayTimeout->timeoutExpired();
|
||||||
sock_.getEventBase()->cancelTimeout(
|
|
||||||
happyEyeballsState_->connAttemptDelayTimeout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
folly::Optional<int> secondSocketErrno;
|
folly::Optional<int> secondSocketErrno;
|
||||||
|
@@ -77,13 +77,11 @@ void QuicTransportBase::scheduleTimeout(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void QuicTransportBase::cancelTimeout(QuicTimerCallback* callback) {
|
void QuicTransportBase::cancelTimeout(QuicTimerCallback* callback) {
|
||||||
if (evb_) {
|
callback->cancelTimerCallback();
|
||||||
evb_->cancelTimeout(callback);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QuicTransportBase::isTimeoutScheduled(QuicTimerCallback* callback) const {
|
bool QuicTransportBase::isTimeoutScheduled(QuicTimerCallback* callback) const {
|
||||||
return evb_ ? evb_->isTimeoutScheduled(callback) : false;
|
return callback->isTimerCallbackScheduled();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuicTransportBase::setPacingTimer(
|
void QuicTransportBase::setPacingTimer(
|
||||||
|
@@ -262,7 +262,7 @@ class TestQuicTransport
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::chrono::milliseconds getLossTimeoutRemainingTime() {
|
std::chrono::milliseconds getLossTimeoutRemainingTime() {
|
||||||
return evb_->getTimeoutTimeRemaining(&lossTimeout_);
|
return lossTimeout_.getTimerCallbackTimeRemaining();
|
||||||
}
|
}
|
||||||
|
|
||||||
void onReadData(const folly::SocketAddress&, ReceivedUdpPacket&& udpPacket)
|
void onReadData(const folly::SocketAddress&, ReceivedUdpPacket&& udpPacket)
|
||||||
@@ -365,7 +365,7 @@ class TestQuicTransport
|
|||||||
}
|
}
|
||||||
|
|
||||||
void invokeCancelPingTimeout() {
|
void invokeCancelPingTimeout() {
|
||||||
evb_->cancelTimeout(&pingTimeout_);
|
pingTimeout_.cancelTimerCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
void invokeHandlePingCallbacks() {
|
void invokeHandlePingCallbacks() {
|
||||||
@@ -377,10 +377,7 @@ class TestQuicTransport
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool isPingTimeoutScheduled() {
|
bool isPingTimeoutScheduled() {
|
||||||
if (evb_->isTimeoutScheduled(&pingTimeout_)) {
|
return pingTimeout_.isTimerCallbackScheduled();
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& writeLooper() {
|
auto& writeLooper() {
|
||||||
|
@@ -2224,14 +2224,15 @@ TEST_F(QuicTransportTest, SendPathChallenge) {
|
|||||||
EXPECT_FALSE(conn.pendingEvents.schedulePathValidationTimeout);
|
EXPECT_FALSE(conn.pendingEvents.schedulePathValidationTimeout);
|
||||||
EXPECT_FALSE(conn.outstandingPathValidation);
|
EXPECT_FALSE(conn.outstandingPathValidation);
|
||||||
EXPECT_FALSE(
|
EXPECT_FALSE(
|
||||||
qEvb_->isTimeoutScheduled(&transport_->getPathValidationTimeout()));
|
transport_->getPathValidationTimeout().isTimerCallbackScheduled());
|
||||||
|
|
||||||
loopForWrites();
|
loopForWrites();
|
||||||
EXPECT_FALSE(conn.pendingEvents.pathChallenge);
|
EXPECT_FALSE(conn.pendingEvents.pathChallenge);
|
||||||
EXPECT_TRUE(conn.pendingEvents.schedulePathValidationTimeout);
|
EXPECT_TRUE(conn.pendingEvents.schedulePathValidationTimeout);
|
||||||
EXPECT_TRUE(conn.outstandingPathValidation);
|
EXPECT_TRUE(conn.outstandingPathValidation);
|
||||||
EXPECT_EQ(conn.outstandingPathValidation, pathChallenge);
|
EXPECT_EQ(conn.outstandingPathValidation, pathChallenge);
|
||||||
EXPECT_TRUE(
|
EXPECT_TRUE(
|
||||||
qEvb_->isTimeoutScheduled(&transport_->getPathValidationTimeout()));
|
transport_->getPathValidationTimeout().isTimerCallbackScheduled());
|
||||||
|
|
||||||
EXPECT_EQ(1, transport_->getConnectionState().outstandings.packets.size());
|
EXPECT_EQ(1, transport_->getConnectionState().outstandings.packets.size());
|
||||||
auto packet =
|
auto packet =
|
||||||
@@ -2267,18 +2268,18 @@ TEST_F(QuicTransportTest, PathValidationTimeoutExpired) {
|
|||||||
EXPECT_FALSE(conn.pendingEvents.schedulePathValidationTimeout);
|
EXPECT_FALSE(conn.pendingEvents.schedulePathValidationTimeout);
|
||||||
EXPECT_FALSE(conn.outstandingPathValidation);
|
EXPECT_FALSE(conn.outstandingPathValidation);
|
||||||
EXPECT_FALSE(
|
EXPECT_FALSE(
|
||||||
qEvb_->isTimeoutScheduled(&transport_->getPathValidationTimeout()));
|
transport_->getPathValidationTimeout().isTimerCallbackScheduled());
|
||||||
loopForWrites();
|
loopForWrites();
|
||||||
EXPECT_FALSE(conn.pendingEvents.pathChallenge);
|
EXPECT_FALSE(conn.pendingEvents.pathChallenge);
|
||||||
EXPECT_TRUE(conn.pendingEvents.schedulePathValidationTimeout);
|
EXPECT_TRUE(conn.pendingEvents.schedulePathValidationTimeout);
|
||||||
EXPECT_TRUE(conn.outstandingPathValidation);
|
EXPECT_TRUE(conn.outstandingPathValidation);
|
||||||
EXPECT_EQ(conn.outstandingPathValidation, pathChallenge);
|
EXPECT_EQ(conn.outstandingPathValidation, pathChallenge);
|
||||||
EXPECT_TRUE(
|
EXPECT_TRUE(
|
||||||
qEvb_->isTimeoutScheduled(&transport_->getPathValidationTimeout()));
|
transport_->getPathValidationTimeout().isTimerCallbackScheduled());
|
||||||
|
|
||||||
EXPECT_EQ(1, transport_->getConnectionState().outstandings.packets.size());
|
EXPECT_EQ(1, transport_->getConnectionState().outstandings.packets.size());
|
||||||
|
|
||||||
qEvb_->cancelTimeout(&transport_->getPathValidationTimeout());
|
transport_->getPathValidationTimeout().cancelTimerCallback();
|
||||||
transport_->getPathValidationTimeout().timeoutExpired();
|
transport_->getPathValidationTimeout().timeoutExpired();
|
||||||
EXPECT_FALSE(conn.pendingEvents.schedulePathValidationTimeout);
|
EXPECT_FALSE(conn.pendingEvents.schedulePathValidationTimeout);
|
||||||
EXPECT_FALSE(conn.outstandingPathValidation);
|
EXPECT_FALSE(conn.outstandingPathValidation);
|
||||||
@@ -2303,12 +2304,12 @@ TEST_F(QuicTransportTest, SendPathValidationWhileThereIsOutstandingOne) {
|
|||||||
EXPECT_TRUE(conn.outstandingPathValidation);
|
EXPECT_TRUE(conn.outstandingPathValidation);
|
||||||
EXPECT_EQ(conn.outstandingPathValidation, pathChallenge);
|
EXPECT_EQ(conn.outstandingPathValidation, pathChallenge);
|
||||||
EXPECT_TRUE(
|
EXPECT_TRUE(
|
||||||
qEvb_->isTimeoutScheduled(&transport_->getPathValidationTimeout()));
|
transport_->getPathValidationTimeout().isTimerCallbackScheduled());
|
||||||
|
|
||||||
EXPECT_EQ(1, transport_->getConnectionState().outstandings.packets.size());
|
EXPECT_EQ(1, transport_->getConnectionState().outstandings.packets.size());
|
||||||
|
|
||||||
PathChallengeFrame pathChallenge2(456);
|
PathChallengeFrame pathChallenge2(456);
|
||||||
qEvb_->cancelTimeout(&transport_->getPathValidationTimeout());
|
transport_->getPathValidationTimeout().cancelTimerCallback();
|
||||||
conn.pendingEvents.schedulePathValidationTimeout = false;
|
conn.pendingEvents.schedulePathValidationTimeout = false;
|
||||||
conn.outstandingPathValidation = folly::none;
|
conn.outstandingPathValidation = folly::none;
|
||||||
conn.pendingEvents.pathChallenge = pathChallenge2;
|
conn.pendingEvents.pathChallenge = pathChallenge2;
|
||||||
@@ -2321,7 +2322,7 @@ TEST_F(QuicTransportTest, SendPathValidationWhileThereIsOutstandingOne) {
|
|||||||
EXPECT_TRUE(conn.pendingEvents.schedulePathValidationTimeout);
|
EXPECT_TRUE(conn.pendingEvents.schedulePathValidationTimeout);
|
||||||
EXPECT_EQ(conn.outstandingPathValidation, pathChallenge2);
|
EXPECT_EQ(conn.outstandingPathValidation, pathChallenge2);
|
||||||
EXPECT_TRUE(
|
EXPECT_TRUE(
|
||||||
qEvb_->isTimeoutScheduled(&transport_->getPathValidationTimeout()));
|
transport_->getPathValidationTimeout().isTimerCallbackScheduled());
|
||||||
|
|
||||||
EXPECT_EQ(2, transport_->getConnectionState().outstandings.packets.size());
|
EXPECT_EQ(2, transport_->getConnectionState().outstandings.packets.size());
|
||||||
}
|
}
|
||||||
@@ -2432,7 +2433,7 @@ TEST_F(QuicTransportTest, DoNotResendLostPathChallengeIfNotOutstanding) {
|
|||||||
->packet;
|
->packet;
|
||||||
|
|
||||||
// Fire path validation timer
|
// Fire path validation timer
|
||||||
qEvb_->cancelTimeout(&transport_->getPathValidationTimeout());
|
transport_->getPathValidationTimeout().cancelTimerCallback();
|
||||||
transport_->getPathValidationTimeout().timeoutExpired();
|
transport_->getPathValidationTimeout().timeoutExpired();
|
||||||
|
|
||||||
EXPECT_FALSE(conn.pendingEvents.pathChallenge);
|
EXPECT_FALSE(conn.pendingEvents.pathChallenge);
|
||||||
@@ -4446,41 +4447,41 @@ TEST_F(QuicTransportTest, NoStream) {
|
|||||||
|
|
||||||
TEST_F(QuicTransportTest, CancelAckTimeout) {
|
TEST_F(QuicTransportTest, CancelAckTimeout) {
|
||||||
qEvb_->scheduleTimeout(transport_->getAckTimeout(), 1000000ms);
|
qEvb_->scheduleTimeout(transport_->getAckTimeout(), 1000000ms);
|
||||||
EXPECT_TRUE(qEvb_->isTimeoutScheduled(transport_->getAckTimeout()));
|
EXPECT_TRUE(transport_->getAckTimeout()->isTimerCallbackScheduled());
|
||||||
transport_->getConnectionState().pendingEvents.scheduleAckTimeout = false;
|
transport_->getConnectionState().pendingEvents.scheduleAckTimeout = false;
|
||||||
transport_->onNetworkData(
|
transport_->onNetworkData(
|
||||||
SocketAddress("::1", 10128),
|
SocketAddress("::1", 10128),
|
||||||
NetworkData(IOBuf::copyBuffer("MTA New York Service"), Clock::now()));
|
NetworkData(IOBuf::copyBuffer("MTA New York Service"), Clock::now()));
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(transport_->getAckTimeout()));
|
EXPECT_FALSE(transport_->getAckTimeout()->isTimerCallbackScheduled());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(QuicTransportTest, ScheduleAckTimeout) {
|
TEST_F(QuicTransportTest, ScheduleAckTimeout) {
|
||||||
// Make srtt large so we will use kMinAckTimeout
|
// Make srtt large so we will use kMinAckTimeout
|
||||||
transport_->getConnectionState().lossState.srtt = 25000000us;
|
transport_->getConnectionState().lossState.srtt = 25000000us;
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(transport_->getAckTimeout()));
|
EXPECT_FALSE(transport_->getAckTimeout()->isTimerCallbackScheduled());
|
||||||
transport_->getConnectionState().pendingEvents.scheduleAckTimeout = true;
|
transport_->getConnectionState().pendingEvents.scheduleAckTimeout = true;
|
||||||
transport_->onNetworkData(
|
transport_->onNetworkData(
|
||||||
SocketAddress("::1", 10003),
|
SocketAddress("::1", 10003),
|
||||||
NetworkData(
|
NetworkData(
|
||||||
IOBuf::copyBuffer("Never on time, always timeout"), Clock::now()));
|
IOBuf::copyBuffer("Never on time, always timeout"), Clock::now()));
|
||||||
EXPECT_TRUE(qEvb_->isTimeoutScheduled(transport_->getAckTimeout()));
|
EXPECT_TRUE(transport_->getAckTimeout()->isTimerCallbackScheduled());
|
||||||
EXPECT_NEAR(
|
EXPECT_NEAR(
|
||||||
qEvb_->getTimeoutTimeRemaining(transport_->getAckTimeout()).count(),
|
transport_->getAckTimeout()->getTimerCallbackTimeRemaining().count(),
|
||||||
25,
|
25,
|
||||||
5);
|
5);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(QuicTransportTest, ScheduleAckTimeoutSRTTFactor) {
|
TEST_F(QuicTransportTest, ScheduleAckTimeoutSRTTFactor) {
|
||||||
transport_->getConnectionState().lossState.srtt = 50ms;
|
transport_->getConnectionState().lossState.srtt = 50ms;
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(transport_->getAckTimeout()));
|
EXPECT_FALSE(transport_->getAckTimeout()->isTimerCallbackScheduled());
|
||||||
transport_->getConnectionState().pendingEvents.scheduleAckTimeout = true;
|
transport_->getConnectionState().pendingEvents.scheduleAckTimeout = true;
|
||||||
transport_->onNetworkData(
|
transport_->onNetworkData(
|
||||||
SocketAddress("::1", 10003),
|
SocketAddress("::1", 10003),
|
||||||
NetworkData(
|
NetworkData(
|
||||||
IOBuf::copyBuffer("Never on time, always timeout"), Clock::now()));
|
IOBuf::copyBuffer("Never on time, always timeout"), Clock::now()));
|
||||||
EXPECT_TRUE(qEvb_->isTimeoutScheduled(transport_->getAckTimeout()));
|
EXPECT_TRUE(transport_->getAckTimeout()->isTimerCallbackScheduled());
|
||||||
EXPECT_NEAR(
|
EXPECT_NEAR(
|
||||||
qEvb_->getTimeoutTimeRemaining(transport_->getAckTimeout()).count(),
|
transport_->getAckTimeout()->getTimerCallbackTimeRemaining().count(),
|
||||||
50 / 4,
|
50 / 4,
|
||||||
2);
|
2);
|
||||||
}
|
}
|
||||||
@@ -4491,15 +4492,15 @@ TEST_F(QuicTransportTest, ScheduleAckTimeoutAckFreq) {
|
|||||||
transport_->getConnectionState()
|
transport_->getConnectionState()
|
||||||
.ackStates.appDataAckState.ackFrequencySequenceNumber = 1;
|
.ackStates.appDataAckState.ackFrequencySequenceNumber = 1;
|
||||||
transport_->getConnectionState().ackStates.maxAckDelay = 50ms / 3;
|
transport_->getConnectionState().ackStates.maxAckDelay = 50ms / 3;
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(transport_->getAckTimeout()));
|
EXPECT_FALSE(transport_->getAckTimeout()->isTimerCallbackScheduled());
|
||||||
transport_->getConnectionState().pendingEvents.scheduleAckTimeout = true;
|
transport_->getConnectionState().pendingEvents.scheduleAckTimeout = true;
|
||||||
transport_->onNetworkData(
|
transport_->onNetworkData(
|
||||||
SocketAddress("::1", 10003),
|
SocketAddress("::1", 10003),
|
||||||
NetworkData(
|
NetworkData(
|
||||||
IOBuf::copyBuffer("Never on time, always timeout"), Clock::now()));
|
IOBuf::copyBuffer("Never on time, always timeout"), Clock::now()));
|
||||||
EXPECT_TRUE(qEvb_->isTimeoutScheduled(transport_->getAckTimeout()));
|
EXPECT_TRUE(transport_->getAckTimeout()->isTimerCallbackScheduled());
|
||||||
EXPECT_NEAR(
|
EXPECT_NEAR(
|
||||||
qEvb_->getTimeoutTimeRemaining(transport_->getAckTimeout()).count(),
|
transport_->getAckTimeout()->getTimerCallbackTimeRemaining().count(),
|
||||||
50 / 3,
|
50 / 3,
|
||||||
2);
|
2);
|
||||||
}
|
}
|
||||||
@@ -4508,28 +4509,28 @@ TEST_F(QuicTransportTest, ScheduleAckTimeoutFromMaxAckDelay) {
|
|||||||
// Make srtt large so we will use maxAckDelay
|
// Make srtt large so we will use maxAckDelay
|
||||||
transport_->getConnectionState().lossState.srtt = 25000000us;
|
transport_->getConnectionState().lossState.srtt = 25000000us;
|
||||||
transport_->getConnectionState().ackStates.maxAckDelay = 10ms;
|
transport_->getConnectionState().ackStates.maxAckDelay = 10ms;
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(transport_->getAckTimeout()));
|
EXPECT_FALSE(transport_->getAckTimeout()->isTimerCallbackScheduled());
|
||||||
transport_->getConnectionState().pendingEvents.scheduleAckTimeout = true;
|
transport_->getConnectionState().pendingEvents.scheduleAckTimeout = true;
|
||||||
transport_->onNetworkData(
|
transport_->onNetworkData(
|
||||||
SocketAddress("::1", 10003),
|
SocketAddress("::1", 10003),
|
||||||
NetworkData(
|
NetworkData(
|
||||||
IOBuf::copyBuffer("Never on time, always timeout"), Clock::now()));
|
IOBuf::copyBuffer("Never on time, always timeout"), Clock::now()));
|
||||||
EXPECT_TRUE(qEvb_->isTimeoutScheduled(transport_->getAckTimeout()));
|
EXPECT_TRUE(transport_->getAckTimeout()->isTimerCallbackScheduled());
|
||||||
EXPECT_NEAR(
|
EXPECT_NEAR(
|
||||||
qEvb_->getTimeoutTimeRemaining(transport_->getAckTimeout()).count(),
|
transport_->getAckTimeout()->getTimerCallbackTimeRemaining().count(),
|
||||||
10,
|
10,
|
||||||
5);
|
5);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(QuicTransportTest, CloseTransportCancelsAckTimeout) {
|
TEST_F(QuicTransportTest, CloseTransportCancelsAckTimeout) {
|
||||||
transport_->getConnectionState().lossState.srtt = 25000000us;
|
transport_->getConnectionState().lossState.srtt = 25000000us;
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(transport_->getAckTimeout()));
|
EXPECT_FALSE(transport_->getAckTimeout()->isTimerCallbackScheduled());
|
||||||
transport_->getConnectionState().pendingEvents.scheduleAckTimeout = true;
|
transport_->getConnectionState().pendingEvents.scheduleAckTimeout = true;
|
||||||
transport_->onNetworkData(
|
transport_->onNetworkData(
|
||||||
SocketAddress("::1", 10003),
|
SocketAddress("::1", 10003),
|
||||||
NetworkData(
|
NetworkData(
|
||||||
IOBuf::copyBuffer("Never on time, always timeout"), Clock::now()));
|
IOBuf::copyBuffer("Never on time, always timeout"), Clock::now()));
|
||||||
EXPECT_TRUE(qEvb_->isTimeoutScheduled(transport_->getAckTimeout()));
|
EXPECT_TRUE(transport_->getAckTimeout()->isTimerCallbackScheduled());
|
||||||
// We need to send some packets, otherwise loss timer won't be scheduled
|
// We need to send some packets, otherwise loss timer won't be scheduled
|
||||||
auto stream = transport_->createBidirectionalStream().value();
|
auto stream = transport_->createBidirectionalStream().value();
|
||||||
auto buf = buildRandomInputData(kDefaultUDPSendPacketLen + 20);
|
auto buf = buildRandomInputData(kDefaultUDPSendPacketLen + 20);
|
||||||
@@ -4541,7 +4542,7 @@ TEST_F(QuicTransportTest, CloseTransportCancelsAckTimeout) {
|
|||||||
EXPECT_TRUE(transport_->isLossTimeoutScheduled());
|
EXPECT_TRUE(transport_->isLossTimeoutScheduled());
|
||||||
|
|
||||||
transport_->closeNow(folly::none);
|
transport_->closeNow(folly::none);
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(transport_->getAckTimeout()));
|
EXPECT_FALSE(transport_->getAckTimeout()->isTimerCallbackScheduled());
|
||||||
EXPECT_FALSE(transport_->isLossTimeoutScheduled());
|
EXPECT_FALSE(transport_->isLossTimeoutScheduled());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4568,7 +4569,7 @@ TEST_F(QuicTransportTest, IdleTimeoutMin) {
|
|||||||
transport_->getConnectionState().peerIdleTimeout = 15s;
|
transport_->getConnectionState().peerIdleTimeout = 15s;
|
||||||
transport_->setIdleTimerNow();
|
transport_->setIdleTimerNow();
|
||||||
EXPECT_NEAR(
|
EXPECT_NEAR(
|
||||||
qEvb_->getTimeoutTimeRemaining(&transport_->idleTimeout()).count(),
|
transport_->idleTimeout().getTimerCallbackTimeRemaining().count(),
|
||||||
15000,
|
15000,
|
||||||
1000);
|
1000);
|
||||||
}
|
}
|
||||||
@@ -4577,16 +4578,16 @@ TEST_F(QuicTransportTest, IdleTimeoutLocalDisabled) {
|
|||||||
transport_->getConnectionState().transportSettings.idleTimeout = 0s;
|
transport_->getConnectionState().transportSettings.idleTimeout = 0s;
|
||||||
transport_->getConnectionState().peerIdleTimeout = 15s;
|
transport_->getConnectionState().peerIdleTimeout = 15s;
|
||||||
transport_->setIdleTimerNow();
|
transport_->setIdleTimerNow();
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(&transport_->idleTimeout()));
|
EXPECT_FALSE(transport_->idleTimeout().isTimerCallbackScheduled());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(QuicTransportTest, IdleTimeoutPeerDisabled) {
|
TEST_F(QuicTransportTest, IdleTimeoutPeerDisabled) {
|
||||||
transport_->getConnectionState().transportSettings.idleTimeout = 60s;
|
transport_->getConnectionState().transportSettings.idleTimeout = 60s;
|
||||||
transport_->getConnectionState().peerIdleTimeout = 0s;
|
transport_->getConnectionState().peerIdleTimeout = 0s;
|
||||||
transport_->setIdleTimerNow();
|
transport_->setIdleTimerNow();
|
||||||
ASSERT_TRUE(qEvb_->isTimeoutScheduled(&transport_->idleTimeout()));
|
ASSERT_TRUE(transport_->idleTimeout().isTimerCallbackScheduled());
|
||||||
EXPECT_NEAR(
|
EXPECT_NEAR(
|
||||||
qEvb_->getTimeoutTimeRemaining(&transport_->idleTimeout()).count(),
|
transport_->idleTimeout().getTimerCallbackTimeRemaining().count(),
|
||||||
60000,
|
60000,
|
||||||
1000);
|
1000);
|
||||||
}
|
}
|
||||||
|
@@ -34,7 +34,7 @@ void QuicConnector::onReplaySafe() noexcept {
|
|||||||
if (cb_) {
|
if (cb_) {
|
||||||
cb_->onConnectSuccess();
|
cb_->onConnectSuccess();
|
||||||
}
|
}
|
||||||
qEvb_->cancelTimeout(this);
|
cancelTimerCallback();
|
||||||
cleanUpAndCloseSocket();
|
cleanUpAndCloseSocket();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -41,9 +41,7 @@ class QuicConnector : private quic::QuicSocket::ConnectionSetupCallback,
|
|||||||
~QuicConnector() override {
|
~QuicConnector() override {
|
||||||
// TODO we shouldn't need to do this but just as a safety measure
|
// TODO we shouldn't need to do this but just as a safety measure
|
||||||
// to ensure we don't get a callback after detruction.
|
// to ensure we don't get a callback after detruction.
|
||||||
if (qEvb_) {
|
cancelTimerCallback();
|
||||||
qEvb_->cancelTimeout(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void connect(
|
void connect(
|
||||||
|
@@ -51,8 +51,7 @@ void FunctionLooper::commonLoopBody() noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool FunctionLooper::schedulePacingTimeout() noexcept {
|
bool FunctionLooper::schedulePacingTimeout() noexcept {
|
||||||
if (pacingFunc_ && pacingTimer_ &&
|
if (pacingFunc_ && pacingTimer_ && !isTimerCallbackScheduled()) {
|
||||||
!pacingTimer_->isTimerCallbackScheduled(this)) {
|
|
||||||
auto timeUntilWrite = (*pacingFunc_)();
|
auto timeUntilWrite = (*pacingFunc_)();
|
||||||
if (timeUntilWrite != 0us) {
|
if (timeUntilWrite != 0us) {
|
||||||
nextPacingTime_ = Clock::now() + timeUntilWrite;
|
nextPacingTime_ = Clock::now() + timeUntilWrite;
|
||||||
@@ -78,22 +77,21 @@ void FunctionLooper::run(bool thisIteration) noexcept {
|
|||||||
<< " in loop body and using pacing - not rescheduling";
|
<< " in loop body and using pacing - not rescheduling";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (evb_->isLoopCallbackScheduled(this) ||
|
if (isLoopCallbackScheduled() ||
|
||||||
(!fireLoopEarly_ && pacingTimer_ &&
|
(!fireLoopEarly_ && pacingTimer_ && isTimerCallbackScheduled())) {
|
||||||
pacingTimer_->isTimerCallbackScheduled(this))) {
|
|
||||||
VLOG(10) << __func__ << ": " << type_ << " already scheduled";
|
VLOG(10) << __func__ << ": " << type_ << " already scheduled";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// If we are pacing, we're about to write again, if it's close, just write
|
// If we are pacing, we're about to write again, if it's close, just write
|
||||||
// now.
|
// now.
|
||||||
if (pacingTimer_ && pacingTimer_->isTimerCallbackScheduled(this)) {
|
if (pacingTimer_ && isTimerCallbackScheduled()) {
|
||||||
auto n = Clock::now();
|
auto n = Clock::now();
|
||||||
auto timeUntilWrite = nextPacingTime_ < n
|
auto timeUntilWrite = nextPacingTime_ < n
|
||||||
? 0us
|
? 0us
|
||||||
: std::chrono::duration_cast<std::chrono::milliseconds>(
|
: std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||||
nextPacingTime_ - n);
|
nextPacingTime_ - n);
|
||||||
if (timeUntilWrite <= 1ms) {
|
if (timeUntilWrite <= 1ms) {
|
||||||
pacingTimer_->cancelTimeout(this);
|
cancelTimerCallback();
|
||||||
// The next loop is good enough
|
// The next loop is good enough
|
||||||
thisIteration = false;
|
thisIteration = false;
|
||||||
} else {
|
} else {
|
||||||
@@ -107,10 +105,10 @@ void FunctionLooper::stop() noexcept {
|
|||||||
VLOG(10) << __func__ << ": " << type_;
|
VLOG(10) << __func__ << ": " << type_;
|
||||||
running_ = false;
|
running_ = false;
|
||||||
if (evb_) {
|
if (evb_) {
|
||||||
evb_->cancelLoopCallback(this);
|
cancelLoopCallback();
|
||||||
}
|
}
|
||||||
if (pacingTimer_) {
|
if (pacingTimer_) {
|
||||||
pacingTimer_->cancelTimeout(this);
|
cancelTimerCallback();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,11 +117,11 @@ bool FunctionLooper::isRunning() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool FunctionLooper::isPacingScheduled() {
|
bool FunctionLooper::isPacingScheduled() {
|
||||||
return pacingTimer_ && pacingTimer_->isTimerCallbackScheduled(this);
|
return pacingTimer_ && isTimerCallbackScheduled();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FunctionLooper::isLoopCallbackScheduled() {
|
bool FunctionLooper::isLoopCallbackScheduled() {
|
||||||
return evb_->isLoopCallbackScheduled(this);
|
return QuicEventBaseLoopCallback::isLoopCallbackScheduled();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FunctionLooper::attachEventBase(std::shared_ptr<QuicEventBase> evb) {
|
void FunctionLooper::attachEventBase(std::shared_ptr<QuicEventBase> evb) {
|
||||||
@@ -138,7 +136,7 @@ void FunctionLooper::detachEventBase() {
|
|||||||
DCHECK(evb_ && evb_->isInEventBaseThread());
|
DCHECK(evb_ && evb_->isInEventBaseThread());
|
||||||
stop();
|
stop();
|
||||||
if (pacingTimer_) {
|
if (pacingTimer_) {
|
||||||
pacingTimer_->cancelTimeout(this);
|
cancelTimerCallback();
|
||||||
}
|
}
|
||||||
evb_ = nullptr;
|
evb_ = nullptr;
|
||||||
}
|
}
|
||||||
|
@@ -13,30 +13,17 @@ FollyQuicEventBase::FollyQuicEventBase(folly::EventBase* evb) {
|
|||||||
backingEvb_ = evb;
|
backingEvb_ = evb;
|
||||||
}
|
}
|
||||||
|
|
||||||
FollyQuicEventBase::~FollyQuicEventBase() {
|
FollyQuicEventBase::~FollyQuicEventBase() = default;
|
||||||
loopCallbackWrappers_.clear_and_dispose([](LoopCallbackWrapper* wrapper) {
|
|
||||||
wrapper->cancelLoopCallback();
|
|
||||||
delete wrapper;
|
|
||||||
});
|
|
||||||
timerCallbackWrappers_.clear_and_dispose([](TimerCallbackWrapper* wrapper) {
|
|
||||||
wrapper->cancelTimeout();
|
|
||||||
delete wrapper;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void FollyQuicEventBase::runInLoop(
|
void FollyQuicEventBase::runInLoop(
|
||||||
QuicEventBaseLoopCallback* callback,
|
QuicEventBaseLoopCallback* callback,
|
||||||
bool thisIteration) {
|
bool thisIteration) {
|
||||||
auto wrapper = static_cast<LoopCallbackWrapper*>(getImplHandle(callback));
|
auto wrapper = static_cast<LoopCallbackWrapper*>(getImplHandle(callback));
|
||||||
if (!wrapper) {
|
if (!wrapper) {
|
||||||
wrapper = new LoopCallbackWrapper(callback, this);
|
wrapper = new LoopCallbackWrapper(callback);
|
||||||
loopCallbackWrappers_.push_back(*wrapper);
|
|
||||||
setImplHandle(callback, wrapper);
|
setImplHandle(callback, wrapper);
|
||||||
return backingEvb_->runInLoop(wrapper, thisIteration);
|
|
||||||
} else {
|
|
||||||
// This callback is already scheduled.
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
return backingEvb_->runInLoop(wrapper, thisIteration);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FollyQuicEventBase::runInLoop(
|
void FollyQuicEventBase::runInLoop(
|
||||||
@@ -100,13 +87,12 @@ bool FollyQuicEventBase::scheduleTimeoutHighRes(
|
|||||||
}
|
}
|
||||||
auto wrapper =
|
auto wrapper =
|
||||||
static_cast<TimerCallbackWrapper*>(getImplHandle(timerCallback));
|
static_cast<TimerCallbackWrapper*>(getImplHandle(timerCallback));
|
||||||
if (wrapper != nullptr) {
|
if (wrapper == nullptr) {
|
||||||
// This callback is already scheduled.
|
// This is the first time this timer callback is getting scheduled. Create a
|
||||||
return false;
|
// wrapper for it.
|
||||||
|
wrapper = new TimerCallbackWrapper(timerCallback, this);
|
||||||
|
setImplHandle(timerCallback, wrapper);
|
||||||
}
|
}
|
||||||
wrapper = new TimerCallbackWrapper(timerCallback, this);
|
|
||||||
timerCallbackWrappers_.push_back(*wrapper);
|
|
||||||
setImplHandle(timerCallback, wrapper);
|
|
||||||
return backingEvb_->scheduleTimeoutHighRes(wrapper, timeout);
|
return backingEvb_->scheduleTimeoutHighRes(wrapper, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,73 +105,17 @@ void FollyQuicEventBase::scheduleTimeout(
|
|||||||
}
|
}
|
||||||
auto wrapper =
|
auto wrapper =
|
||||||
static_cast<TimerCallbackWrapper*>(getImplHandle(timerCallback));
|
static_cast<TimerCallbackWrapper*>(getImplHandle(timerCallback));
|
||||||
if (wrapper != nullptr) {
|
if (wrapper == nullptr) {
|
||||||
// This callback is already scheduled.
|
// This is the first time this timer callback is getting scheduled. Create a
|
||||||
return;
|
// wrapper for it.
|
||||||
|
wrapper = new TimerCallbackWrapper(timerCallback, this);
|
||||||
|
setImplHandle(timerCallback, wrapper);
|
||||||
}
|
}
|
||||||
wrapper = new TimerCallbackWrapper(timerCallback, this);
|
|
||||||
timerCallbackWrappers_.push_back(*wrapper);
|
|
||||||
setImplHandle(timerCallback, wrapper);
|
|
||||||
backingEvb_->timer().scheduleTimeout(wrapper, timeout);
|
backingEvb_->timer().scheduleTimeout(wrapper, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FollyQuicEventBase::isTimeoutScheduled(
|
|
||||||
QuicTimerCallback* timerCallback) const {
|
|
||||||
if (!timerCallback || !getImplHandle(timerCallback)) {
|
|
||||||
// There is no wrapper. Nothing is scheduled.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
auto wrapper =
|
|
||||||
static_cast<TimerCallbackWrapper*>(getImplHandle(timerCallback));
|
|
||||||
return wrapper->isScheduled();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::chrono::milliseconds FollyQuicEventBase::getTimeoutTimeRemaining(
|
|
||||||
QuicTimerCallback* timerCallback) const {
|
|
||||||
if (!timerCallback || !getImplHandle(timerCallback)) {
|
|
||||||
// There is no wrapper. Nothing to check.
|
|
||||||
return std::chrono::milliseconds(0);
|
|
||||||
}
|
|
||||||
auto wrapper =
|
|
||||||
static_cast<TimerCallbackWrapper*>(getImplHandle(timerCallback));
|
|
||||||
return wrapper->getTimeRemaining();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FollyQuicEventBase::cancelTimeout(QuicTimerCallback* timerCallback) {
|
|
||||||
if (!timerCallback || !getImplHandle(timerCallback)) {
|
|
||||||
// There is no wrapper. Nothing to cancel.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto wrapper =
|
|
||||||
static_cast<TimerCallbackWrapper*>(getImplHandle(timerCallback));
|
|
||||||
unregisterTimerCallbackInternal(timerCallback);
|
|
||||||
wrapper->cancelTimeout();
|
|
||||||
delete wrapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::chrono::milliseconds FollyQuicEventBase::getTimerTickInterval() const {
|
std::chrono::milliseconds FollyQuicEventBase::getTimerTickInterval() const {
|
||||||
return backingEvb_->timer().getTickInterval();
|
return backingEvb_->timer().getTickInterval();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FollyQuicEventBase::cancelLoopCallback(
|
|
||||||
QuicEventBaseLoopCallback* callback) {
|
|
||||||
auto wrapper = static_cast<LoopCallbackWrapper*>(getImplHandle(callback));
|
|
||||||
if (!wrapper) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
unregisterLoopCallbackInternal(callback);
|
|
||||||
wrapper->cancelLoopCallback();
|
|
||||||
delete wrapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FollyQuicEventBase::isLoopCallbackScheduled(
|
|
||||||
QuicEventBaseLoopCallback* callback) const {
|
|
||||||
auto wrapper =
|
|
||||||
static_cast<const LoopCallbackWrapper*>(getImplHandle(callback));
|
|
||||||
if (!wrapper) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return wrapper->isLoopCallbackScheduled();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace quic
|
} // namespace quic
|
||||||
|
@@ -11,7 +11,6 @@
|
|||||||
|
|
||||||
#include <quic/common/events/QuicEventBase.h>
|
#include <quic/common/events/QuicEventBase.h>
|
||||||
|
|
||||||
#include <folly/IntrusiveList.h>
|
|
||||||
#include <folly/io/async/EventBase.h>
|
#include <folly/io/async/EventBase.h>
|
||||||
#include <folly/io/async/HHWheelTimer-fwd.h>
|
#include <folly/io/async/HHWheelTimer-fwd.h>
|
||||||
|
|
||||||
@@ -66,42 +65,13 @@ class FollyQuicEventBase : public QuicEventBase {
|
|||||||
QuicTimerCallback* callback,
|
QuicTimerCallback* callback,
|
||||||
std::chrono::milliseconds timeout) override;
|
std::chrono::milliseconds timeout) override;
|
||||||
|
|
||||||
bool isTimeoutScheduled(QuicTimerCallback* callback) const override;
|
|
||||||
|
|
||||||
std::chrono::milliseconds getTimeoutTimeRemaining(
|
|
||||||
QuicTimerCallback* callback) const override;
|
|
||||||
|
|
||||||
void cancelTimeout(QuicTimerCallback* callback) override;
|
|
||||||
|
|
||||||
[[nodiscard]] std::chrono::milliseconds getTimerTickInterval() const override;
|
[[nodiscard]] std::chrono::milliseconds getTimerTickInterval() const override;
|
||||||
|
|
||||||
void cancelLoopCallback(QuicEventBaseLoopCallback* callback) override;
|
|
||||||
|
|
||||||
bool isLoopCallbackScheduled(
|
|
||||||
QuicEventBaseLoopCallback* callback) const override;
|
|
||||||
|
|
||||||
folly::EventBase* getBackingEventBase() {
|
folly::EventBase* getBackingEventBase() {
|
||||||
return backingEvb_;
|
return backingEvb_;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void unregisterLoopCallbackInternal(QuicEventBaseLoopCallback* callback) {
|
|
||||||
auto implHandle =
|
|
||||||
static_cast<LoopCallbackWrapper*>(getImplHandle(callback));
|
|
||||||
CHECK_NOTNULL(implHandle);
|
|
||||||
loopCallbackWrappers_.erase(loopCallbackWrappers_.iterator_to(*implHandle));
|
|
||||||
setImplHandle(callback, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void unregisterTimerCallbackInternal(QuicTimerCallback* callback) {
|
|
||||||
auto implHandle =
|
|
||||||
static_cast<TimerCallbackWrapper*>(getImplHandle(callback));
|
|
||||||
CHECK_NOTNULL(implHandle);
|
|
||||||
timerCallbackWrappers_.erase(
|
|
||||||
timerCallbackWrappers_.iterator_to(*implHandle));
|
|
||||||
setImplHandle(callback, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
class TimerCallbackWrapper : public folly::HHWheelTimer::Callback,
|
class TimerCallbackWrapper : public folly::HHWheelTimer::Callback,
|
||||||
public folly::AsyncTimeout,
|
public folly::AsyncTimeout,
|
||||||
public QuicTimerCallback::TimerCallbackImpl {
|
public QuicTimerCallback::TimerCallbackImpl {
|
||||||
@@ -110,71 +80,77 @@ class FollyQuicEventBase : public QuicEventBase {
|
|||||||
QuicTimerCallback* callback,
|
QuicTimerCallback* callback,
|
||||||
FollyQuicEventBase* evb)
|
FollyQuicEventBase* evb)
|
||||||
: folly::AsyncTimeout(evb->getBackingEventBase()) {
|
: folly::AsyncTimeout(evb->getBackingEventBase()) {
|
||||||
parentEvb_ = evb;
|
|
||||||
callback_ = callback;
|
callback_ = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend class FollyQuicEventBase;
|
friend class FollyQuicEventBase;
|
||||||
|
|
||||||
|
// folly::AsyncTimeout and folly::HHWheelTimer::Callback
|
||||||
void timeoutExpired() noexcept override {
|
void timeoutExpired() noexcept override {
|
||||||
parentEvb_->unregisterTimerCallbackInternal(callback_);
|
|
||||||
callback_->timeoutExpired();
|
callback_->timeoutExpired();
|
||||||
delete this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// folly::HHWheelTimer::Callback
|
||||||
void callbackCanceled() noexcept override {
|
void callbackCanceled() noexcept override {
|
||||||
parentEvb_->unregisterTimerCallbackInternal(callback_);
|
|
||||||
callback_->callbackCanceled();
|
callback_->callbackCanceled();
|
||||||
delete this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isScheduled() noexcept {
|
// QuicTimerCallback::TimerCallbackImpl
|
||||||
return folly::AsyncTimeout::isScheduled() ||
|
void cancelImpl() noexcept override {
|
||||||
folly::HHWheelTimer::Callback::isScheduled();
|
|
||||||
}
|
|
||||||
|
|
||||||
void cancelTimeout() noexcept {
|
|
||||||
folly::AsyncTimeout::cancelTimeout();
|
folly::AsyncTimeout::cancelTimeout();
|
||||||
folly::HHWheelTimer::Callback::cancelTimeout();
|
folly::HHWheelTimer::Callback::cancelTimeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QuicTimerCallback::TimerCallbackImpl
|
||||||
|
[[nodiscard]] bool isScheduledImpl() const noexcept override {
|
||||||
|
return folly::AsyncTimeout::isScheduled() ||
|
||||||
|
folly::HHWheelTimer::Callback::isScheduled();
|
||||||
|
}
|
||||||
|
|
||||||
|
// QuicTimerCallback::TimerCallbackImpl
|
||||||
|
[[nodiscard]] std::chrono::milliseconds getTimeRemainingImpl()
|
||||||
|
const noexcept override {
|
||||||
|
return folly::HHWheelTimer::Callback::getTimeRemaining();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FollyQuicEventBase* parentEvb_;
|
// Hide these functions
|
||||||
|
[[nodiscard]] bool isScheduled() const {
|
||||||
|
return isScheduledImpl();
|
||||||
|
}
|
||||||
|
void cancelTimeout() noexcept {
|
||||||
|
return cancelImpl();
|
||||||
|
}
|
||||||
QuicTimerCallback* callback_;
|
QuicTimerCallback* callback_;
|
||||||
folly::IntrusiveListHook listHook_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class LoopCallbackWrapper
|
class LoopCallbackWrapper
|
||||||
: public folly::EventBase::LoopCallback,
|
: public folly::EventBase::LoopCallback,
|
||||||
public QuicEventBaseLoopCallback::LoopCallbackImpl {
|
public QuicEventBaseLoopCallback::LoopCallbackImpl {
|
||||||
public:
|
public:
|
||||||
explicit LoopCallbackWrapper(
|
explicit LoopCallbackWrapper(QuicEventBaseLoopCallback* callback) {
|
||||||
QuicEventBaseLoopCallback* callback,
|
|
||||||
FollyQuicEventBase* evb) {
|
|
||||||
parentEvb_ = evb;
|
|
||||||
callback_ = callback;
|
callback_ = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend class FollyQuicEventBase;
|
// folly::EventBase::LoopCallback
|
||||||
|
|
||||||
void runLoopCallback() noexcept override {
|
void runLoopCallback() noexcept override {
|
||||||
// We need to remove the callback wrapper from the parent evb's map, call
|
|
||||||
// the callback, then delete this wrapper.
|
|
||||||
parentEvb_->unregisterLoopCallbackInternal(callback_);
|
|
||||||
callback_->runLoopCallback();
|
callback_->runLoopCallback();
|
||||||
delete this;
|
}
|
||||||
|
|
||||||
|
// QuicEventBaseLoopCallback::LoopCallbackImpl
|
||||||
|
void cancelImpl() noexcept override {
|
||||||
|
folly::EventBase::LoopCallback::cancelLoopCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
// QuicEventBaseLoopCallback::LoopCallbackImpl
|
||||||
|
[[nodiscard]] bool isScheduledImpl() const noexcept override {
|
||||||
|
return folly::EventBase::LoopCallback::isLoopCallbackScheduled();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FollyQuicEventBase* parentEvb_;
|
|
||||||
QuicEventBaseLoopCallback* callback_;
|
QuicEventBaseLoopCallback* callback_;
|
||||||
folly::IntrusiveListHook listHook_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
folly::IntrusiveList<LoopCallbackWrapper, &LoopCallbackWrapper::listHook_>
|
|
||||||
loopCallbackWrappers_;
|
|
||||||
folly::IntrusiveList<TimerCallbackWrapper, &TimerCallbackWrapper::listHook_>
|
|
||||||
timerCallbackWrappers_;
|
|
||||||
folly::EventBase* backingEvb_{nullptr};
|
folly::EventBase* backingEvb_{nullptr};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -26,43 +26,18 @@ void HighResQuicTimer::scheduleTimeout(
|
|||||||
// There is no callback. Nothing to schedule.
|
// There is no callback. Nothing to schedule.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (QuicEventBase::getImplHandle(callback)) {
|
auto wrapper = static_cast<TimerCallbackWrapper*>(
|
||||||
// This callback is already scheduled.
|
QuicEventBase::getImplHandle(callback));
|
||||||
return;
|
if (wrapper == nullptr) {
|
||||||
|
// This is the first time this timer callback is getting scheduled. Create a
|
||||||
|
// wrapper for it.
|
||||||
|
wrapper = new TimerCallbackWrapper(callback);
|
||||||
|
QuicEventBase::setImplHandle(callback, wrapper);
|
||||||
}
|
}
|
||||||
auto* wrapper = new TimerCallbackWrapper(callback, this);
|
|
||||||
timerCallbackWrappers_.push_back(*wrapper);
|
|
||||||
QuicEventBase::setImplHandle(callback, wrapper);
|
|
||||||
return wheelTimer_->scheduleTimeout(wrapper, timeout);
|
return wheelTimer_->scheduleTimeout(wrapper, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HighResQuicTimer::isTimerCallbackScheduled(
|
|
||||||
QuicTimerCallback* callback) const {
|
|
||||||
if (!callback || !QuicEventBase::getImplHandle(callback)) {
|
|
||||||
// There is no wrapper. Nothing is scheduled.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
auto wrapper = static_cast<TimerCallbackWrapper*>(
|
|
||||||
QuicEventBase::getImplHandle(callback));
|
|
||||||
return wrapper->isScheduled();
|
|
||||||
}
|
|
||||||
|
|
||||||
void HighResQuicTimer::cancelTimeout(QuicTimerCallback* callback) {
|
|
||||||
if (!callback || !QuicEventBase::getImplHandle(callback)) {
|
|
||||||
// There is no wrapper. Nothing to cancel.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto wrapper = static_cast<TimerCallbackWrapper*>(
|
|
||||||
QuicEventBase::getImplHandle(callback));
|
|
||||||
wrapper->cancelTimeout();
|
|
||||||
unregisterCallbackInternal(callback);
|
|
||||||
delete wrapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
HighResQuicTimer::~HighResQuicTimer() {
|
HighResQuicTimer::~HighResQuicTimer() {
|
||||||
// Resetting the wheel timer cancels all pending timeouts which clears the
|
// Resetting the wheel timer cancels all pending timeouts.
|
||||||
// wrappers.
|
|
||||||
wheelTimer_.reset();
|
wheelTimer_.reset();
|
||||||
CHECK(timerCallbackWrappers_.empty());
|
|
||||||
}
|
}
|
||||||
} // namespace quic
|
} // namespace quic
|
||||||
|
@@ -9,7 +9,6 @@
|
|||||||
|
|
||||||
#include <quic/common/events/QuicTimer.h>
|
#include <quic/common/events/QuicTimer.h>
|
||||||
|
|
||||||
#include <folly/IntrusiveList.h>
|
|
||||||
#include <folly/io/async/EventBase.h>
|
#include <folly/io/async/EventBase.h>
|
||||||
#include <folly/io/async/HHWheelTimer.h>
|
#include <folly/io/async/HHWheelTimer.h>
|
||||||
|
|
||||||
@@ -28,48 +27,44 @@ class HighResQuicTimer : public QuicTimer {
|
|||||||
QuicTimerCallback* callback,
|
QuicTimerCallback* callback,
|
||||||
std::chrono::microseconds timeout) override;
|
std::chrono::microseconds timeout) override;
|
||||||
|
|
||||||
bool isTimerCallbackScheduled(QuicTimerCallback* callback) const override;
|
|
||||||
|
|
||||||
void cancelTimeout(QuicTimerCallback* callback) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void unregisterCallbackInternal(QuicTimerCallback* callback) {
|
|
||||||
QuicEventBase::setImplHandle(callback, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
class TimerCallbackWrapper : public folly::HHWheelTimerHighRes::Callback,
|
class TimerCallbackWrapper : public folly::HHWheelTimerHighRes::Callback,
|
||||||
QuicTimerCallback::TimerCallbackImpl {
|
public QuicTimerCallback::TimerCallbackImpl {
|
||||||
public:
|
public:
|
||||||
explicit TimerCallbackWrapper(
|
explicit TimerCallbackWrapper(QuicTimerCallback* callback) {
|
||||||
QuicTimerCallback* callback,
|
|
||||||
HighResQuicTimer* parentTimer) {
|
|
||||||
parentTimer_ = parentTimer;
|
|
||||||
callback_ = callback;
|
callback_ = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend class HighResQuicTimer;
|
|
||||||
|
|
||||||
void timeoutExpired() noexcept override {
|
void timeoutExpired() noexcept override {
|
||||||
parentTimer_->unregisterCallbackInternal(callback_);
|
|
||||||
callback_->timeoutExpired();
|
callback_->timeoutExpired();
|
||||||
delete this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void callbackCanceled() noexcept override {
|
void callbackCanceled() noexcept override {
|
||||||
parentTimer_->unregisterCallbackInternal(callback_);
|
|
||||||
callback_->callbackCanceled();
|
callback_->callbackCanceled();
|
||||||
delete this;
|
}
|
||||||
|
|
||||||
|
// QuicTimerCallback::TimerCallbackImpl
|
||||||
|
void cancelImpl() noexcept override {
|
||||||
|
folly::HHWheelTimerHighRes::Callback::cancelTimeout();
|
||||||
|
}
|
||||||
|
|
||||||
|
// QuicTimerCallback::TimerCallbackImpl
|
||||||
|
[[nodiscard]] bool isScheduledImpl() const noexcept override {
|
||||||
|
return folly::HHWheelTimerHighRes::Callback::isScheduled();
|
||||||
|
}
|
||||||
|
|
||||||
|
// QuicTimerCallback::TimerCallbackImpl
|
||||||
|
[[nodiscard]] std::chrono::milliseconds getTimeRemainingImpl()
|
||||||
|
const noexcept override {
|
||||||
|
// TODO parametrize this type if it's used anywhere outside of tests
|
||||||
|
return std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||||
|
folly::HHWheelTimerHighRes::Callback::getTimeRemaining());
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HighResQuicTimer* parentTimer_;
|
|
||||||
QuicTimerCallback* callback_;
|
QuicTimerCallback* callback_;
|
||||||
folly::IntrusiveListHook listHook_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
folly::IntrusiveList<TimerCallbackWrapper, &TimerCallbackWrapper::listHook_>
|
|
||||||
timerCallbackWrappers_;
|
|
||||||
|
|
||||||
folly::HHWheelTimerHighRes::UniquePtr wheelTimer_;
|
folly::HHWheelTimerHighRes::UniquePtr wheelTimer_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -11,6 +11,16 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
void libEvTimeoutCallback(
|
||||||
|
struct ev_loop* /* loop */,
|
||||||
|
ev_timer* w,
|
||||||
|
int /* revents */) {
|
||||||
|
auto wrapper =
|
||||||
|
static_cast<quic::LibevQuicEventBase::TimerCallbackWrapper*>(w->data);
|
||||||
|
CHECK(wrapper != nullptr);
|
||||||
|
wrapper->timeoutExpired();
|
||||||
|
}
|
||||||
|
|
||||||
void libEvCheckCallback(
|
void libEvCheckCallback(
|
||||||
struct ev_loop* /* loop */,
|
struct ev_loop* /* loop */,
|
||||||
ev_check* w,
|
ev_check* w,
|
||||||
@@ -44,7 +54,14 @@ void LibevQuicEventBase::runInLoop(
|
|||||||
QuicEventBaseLoopCallback* callback,
|
QuicEventBaseLoopCallback* callback,
|
||||||
bool /* thisIteration */) {
|
bool /* thisIteration */) {
|
||||||
CHECK(isInEventBaseThread());
|
CHECK(isInEventBaseThread());
|
||||||
loopCallbacks_.push_back(callback);
|
auto wrapper = static_cast<LoopCallbackWrapper*>(getImplHandle(callback));
|
||||||
|
if (!wrapper) {
|
||||||
|
wrapper = new LoopCallbackWrapper(callback);
|
||||||
|
QuicEventBase::setImplHandle(callback, wrapper);
|
||||||
|
}
|
||||||
|
if (!wrapper->listHook_.is_linked()) {
|
||||||
|
loopCallbackWrappers_.push_back(*wrapper);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LibevQuicEventBase::runInEventBaseThreadAndWait(
|
void LibevQuicEventBase::runInEventBaseThreadAndWait(
|
||||||
@@ -52,49 +69,53 @@ void LibevQuicEventBase::runInEventBaseThreadAndWait(
|
|||||||
fn();
|
fn();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LibevQuicEventBase::cancelLoopCallback(
|
void LibevQuicEventBase::scheduleTimeout(
|
||||||
QuicEventBaseLoopCallback* callback) {
|
QuicTimerCallback* timerCallback,
|
||||||
auto itr = std::find(loopCallbacks_.begin(), loopCallbacks_.end(), callback);
|
std::chrono::milliseconds timeout) {
|
||||||
if (itr != loopCallbacks_.end()) {
|
scheduleTimeout(
|
||||||
loopCallbacks_.erase(itr);
|
timerCallback,
|
||||||
}
|
std::chrono::duration_cast<std::chrono::microseconds>(timeout));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LibevQuicEventBase::isLoopCallbackScheduled(
|
bool LibevQuicEventBase::scheduleTimeoutHighRes(
|
||||||
QuicEventBaseLoopCallback* callback) const {
|
QuicTimerCallback* timerCallback,
|
||||||
auto itr = std::find(loopCallbacks_.begin(), loopCallbacks_.end(), callback);
|
std::chrono::microseconds timeout) {
|
||||||
return itr != loopCallbacks_.end();
|
scheduleTimeout(timerCallback, timeout);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LibevQuicEventBase::scheduleTimeout(
|
void LibevQuicEventBase::scheduleTimeout(
|
||||||
QuicTimerCallback* callback,
|
QuicTimerCallback* timerCallback,
|
||||||
std::chrono::milliseconds timeout) {
|
std::chrono::microseconds timeout) {
|
||||||
CHECK(!isTimeoutScheduled(callback));
|
if (!timerCallback) {
|
||||||
|
// There is no callback. Nothing to schedule.
|
||||||
auto evTimer = new LibevQuicTimer(ev_loop_, true /*selfOwned*/);
|
return;
|
||||||
|
|
||||||
evTimer->scheduleTimeout(
|
|
||||||
callback, std::chrono::duration_cast<std::chrono::microseconds>(timeout));
|
|
||||||
setImplHandle(callback, evTimer);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LibevQuicEventBase::isTimeoutScheduled(QuicTimerCallback* callback) const {
|
|
||||||
auto evTimer = static_cast<LibevQuicTimer*>(getImplHandle(callback));
|
|
||||||
return evTimer && evTimer->isTimerCallbackScheduled(callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LibevQuicEventBase::cancelTimeout(QuicTimerCallback* callback) {
|
|
||||||
auto evTimer = static_cast<LibevQuicTimer*>(getImplHandle(callback));
|
|
||||||
if (evTimer) {
|
|
||||||
evTimer->cancelTimeout(callback);
|
|
||||||
}
|
}
|
||||||
|
double seconds = timeout.count() / 1000.;
|
||||||
|
auto wrapper =
|
||||||
|
static_cast<TimerCallbackWrapper*>(getImplHandle(timerCallback));
|
||||||
|
if (wrapper == nullptr) {
|
||||||
|
// This is the first time this timer callback is getting scheduled. Create a
|
||||||
|
// wrapper for it.
|
||||||
|
wrapper = new TimerCallbackWrapper(timerCallback, ev_loop_);
|
||||||
|
wrapper->ev_timer_.data = wrapper;
|
||||||
|
ev_timer_init(
|
||||||
|
&wrapper->ev_timer_,
|
||||||
|
libEvTimeoutCallback,
|
||||||
|
seconds /* after */,
|
||||||
|
0. /* repeat */);
|
||||||
|
setImplHandle(timerCallback, wrapper);
|
||||||
|
} else {
|
||||||
|
// We already have a wrapper. Just re-arm it.
|
||||||
|
ev_timer_set(&wrapper->ev_timer_, seconds /* after */, 0. /* repeat */);
|
||||||
|
}
|
||||||
|
|
||||||
|
ev_timer_start(ev_loop_, &wrapper->ev_timer_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LibevQuicEventBase::checkCallbacks() {
|
void LibevQuicEventBase::checkCallbacks() {
|
||||||
std::vector<QuicEventBaseLoopCallback*> callbacks;
|
while (!loopCallbackWrappers_.empty()) {
|
||||||
std::swap(callbacks, loopCallbacks_);
|
loopCallbackWrappers_.front().runLoopCallback();
|
||||||
for (auto cb : callbacks) {
|
|
||||||
cb->runLoopCallback();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -7,8 +7,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <quic/common/events/LibevQuicTimer.h>
|
|
||||||
#include <quic/common/events/QuicEventBase.h>
|
#include <quic/common/events/QuicEventBase.h>
|
||||||
|
#include <quic/common/events/QuicTimer.h>
|
||||||
|
|
||||||
#include <ev.h>
|
#include <ev.h>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <folly/GLog.h>
|
#include <folly/GLog.h>
|
||||||
|
#include <folly/IntrusiveList.h>
|
||||||
|
|
||||||
namespace quic {
|
namespace quic {
|
||||||
/*
|
/*
|
||||||
@@ -25,7 +26,7 @@ namespace quic {
|
|||||||
* (It is copied from the previous interface in
|
* (It is copied from the previous interface in
|
||||||
* quic/common/QuicLibevEventBase.h)
|
* quic/common/QuicLibevEventBase.h)
|
||||||
*/
|
*/
|
||||||
class LibevQuicEventBase : public QuicEventBase {
|
class LibevQuicEventBase : public QuicEventBase, public QuicTimer {
|
||||||
public:
|
public:
|
||||||
explicit LibevQuicEventBase(struct ev_loop* loop);
|
explicit LibevQuicEventBase(struct ev_loop* loop);
|
||||||
~LibevQuicEventBase() override;
|
~LibevQuicEventBase() override;
|
||||||
@@ -42,18 +43,20 @@ class LibevQuicEventBase : public QuicEventBase {
|
|||||||
|
|
||||||
bool isInEventBaseThread() const override;
|
bool isInEventBaseThread() const override;
|
||||||
|
|
||||||
void cancelLoopCallback(QuicEventBaseLoopCallback* /*callback*/) override;
|
// QuicEventBase
|
||||||
|
|
||||||
bool isLoopCallbackScheduled(
|
|
||||||
QuicEventBaseLoopCallback* /*callback*/) const override;
|
|
||||||
|
|
||||||
void scheduleTimeout(
|
void scheduleTimeout(
|
||||||
QuicTimerCallback* callback,
|
QuicTimerCallback* callback,
|
||||||
std::chrono::milliseconds timeout) override;
|
std::chrono::milliseconds timeout) override;
|
||||||
|
|
||||||
bool isTimeoutScheduled(QuicTimerCallback* callback) const override;
|
// QuicEventBase
|
||||||
|
bool scheduleTimeoutHighRes(
|
||||||
|
QuicTimerCallback* /*callback*/,
|
||||||
|
std::chrono::microseconds /*timeout*/) override;
|
||||||
|
|
||||||
void cancelTimeout(QuicTimerCallback* callback) override;
|
// QuicTimer
|
||||||
|
void scheduleTimeout(
|
||||||
|
QuicTimerCallback* callback,
|
||||||
|
std::chrono::microseconds timeout) override;
|
||||||
|
|
||||||
bool loop() override {
|
bool loop() override {
|
||||||
return ev_run(ev_loop_, 0);
|
return ev_run(ev_loop_, 0);
|
||||||
@@ -72,13 +75,6 @@ class LibevQuicEventBase : public QuicEventBase {
|
|||||||
LOG(FATAL) << __func__ << " not supported in LibevQuicEventBase";
|
LOG(FATAL) << __func__ << " not supported in LibevQuicEventBase";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool scheduleTimeoutHighRes(
|
|
||||||
QuicTimerCallback* /*callback*/,
|
|
||||||
std::chrono::microseconds /*timeout*/) override {
|
|
||||||
LOG(FATAL) << __func__ << " not supported in LibevQuicEventBase";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void runAfterDelay(folly::Function<void()> /*cb*/, uint32_t /*milliseconds*/)
|
void runAfterDelay(folly::Function<void()> /*cb*/, uint32_t /*milliseconds*/)
|
||||||
override {
|
override {
|
||||||
LOG(FATAL) << __func__ << " not supported in LibevQuicEventBase";
|
LOG(FATAL) << __func__ << " not supported in LibevQuicEventBase";
|
||||||
@@ -102,24 +98,91 @@ class LibevQuicEventBase : public QuicEventBase {
|
|||||||
return std::chrono::milliseconds(0);
|
return std::chrono::milliseconds(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::chrono::milliseconds getTimeoutTimeRemaining(
|
[[nodiscard]] std::chrono::microseconds getTickInterval() const override {
|
||||||
QuicTimerCallback* /*callback*/) const override {
|
LOG(WARNING) << __func__ << " is not implemented in LibevQuicEventBase";
|
||||||
LOG(FATAL) << __func__ << " not supported in LibevQuicEventBase";
|
return std::chrono::microseconds(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ev_loop* getLibevLoop() {
|
struct ev_loop* getLibevLoop() {
|
||||||
return ev_loop_;
|
return ev_loop_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is public so the libev callback can access it
|
||||||
void checkCallbacks();
|
void checkCallbacks();
|
||||||
|
|
||||||
void timeoutExpired(QuicTimerCallback* callback);
|
// This is public so the libev callback can access it
|
||||||
|
class TimerCallbackWrapper : public QuicTimerCallback::TimerCallbackImpl {
|
||||||
|
public:
|
||||||
|
explicit TimerCallbackWrapper(
|
||||||
|
QuicTimerCallback* callback,
|
||||||
|
struct ev_loop* ev_loop)
|
||||||
|
: callback_(callback), ev_loop_(ev_loop) {}
|
||||||
|
|
||||||
|
friend class LibevQuicEventBase;
|
||||||
|
|
||||||
|
void timeoutExpired() noexcept {
|
||||||
|
callback_->timeoutExpired();
|
||||||
|
}
|
||||||
|
|
||||||
|
void callbackCanceled() noexcept {
|
||||||
|
callback_->callbackCanceled();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cancelImpl() noexcept override {
|
||||||
|
ev_timer_stop(ev_loop_, &ev_timer_);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool isScheduledImpl() const noexcept override {
|
||||||
|
return ev_is_active(&ev_timer_) || ev_is_pending(&ev_timer_);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] std::chrono::milliseconds getTimeRemainingImpl()
|
||||||
|
const noexcept override {
|
||||||
|
LOG(FATAL) << __func__ << " not implemented in LibevQuicEventBase";
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QuicTimerCallback* callback_;
|
||||||
|
struct ev_loop* ev_loop_;
|
||||||
|
ev_timer ev_timer_;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
class LoopCallbackWrapper
|
||||||
|
: public QuicEventBaseLoopCallback::LoopCallbackImpl {
|
||||||
|
public:
|
||||||
|
explicit LoopCallbackWrapper(QuicEventBaseLoopCallback* callback)
|
||||||
|
: callback_(callback) {}
|
||||||
|
|
||||||
|
~LoopCallbackWrapper() override {
|
||||||
|
listHook_.unlink();
|
||||||
|
}
|
||||||
|
|
||||||
|
friend class LibevQuicEventBase;
|
||||||
|
|
||||||
|
void runLoopCallback() noexcept {
|
||||||
|
listHook_.unlink();
|
||||||
|
callback_->runLoopCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cancelImpl() noexcept override {
|
||||||
|
// Removing the callback from the instrusive list is effectively
|
||||||
|
// cancelling it.
|
||||||
|
listHook_.unlink();
|
||||||
|
}
|
||||||
|
[[nodiscard]] bool isScheduledImpl() const noexcept override {
|
||||||
|
return listHook_.is_linked();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QuicEventBaseLoopCallback* callback_;
|
||||||
|
folly::IntrusiveListHook listHook_;
|
||||||
|
};
|
||||||
|
|
||||||
struct ev_loop* ev_loop_{EV_DEFAULT};
|
struct ev_loop* ev_loop_{EV_DEFAULT};
|
||||||
|
|
||||||
// TODO: use an intrusive list instead of a vector for loopCallbacks_
|
folly::IntrusiveList<LoopCallbackWrapper, &LoopCallbackWrapper::listHook_>
|
||||||
std::vector<QuicEventBaseLoopCallback*> loopCallbacks_;
|
loopCallbackWrappers_;
|
||||||
ev_check checkWatcher_;
|
ev_check checkWatcher_;
|
||||||
std::atomic<std::thread::id> loopThreadId_;
|
std::atomic<std::thread::id> loopThreadId_;
|
||||||
};
|
};
|
||||||
|
@@ -1,76 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the MIT license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <quic/common/events/LibevQuicTimer.h>
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
void libEvTimeoutCallback(
|
|
||||||
struct ev_loop* /* loop */,
|
|
||||||
ev_timer* w,
|
|
||||||
int /* revents */) {
|
|
||||||
auto quicTimer = static_cast<quic::LibevQuicTimer*>(w->data);
|
|
||||||
CHECK(quicTimer != nullptr);
|
|
||||||
quicTimer->timeoutExpired();
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
namespace quic {
|
|
||||||
LibevQuicTimer::LibevQuicTimer(struct ev_loop* libevLoop, bool selfOwned) {
|
|
||||||
CHECK(libevLoop != nullptr);
|
|
||||||
ev_loop_ = libevLoop;
|
|
||||||
selfOwned_ = selfOwned;
|
|
||||||
timeoutWatcher_.data = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
LibevQuicTimer::~LibevQuicTimer() {
|
|
||||||
ev_timer_stop(ev_loop_, &timeoutWatcher_);
|
|
||||||
callback_ = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LibevQuicTimer::scheduleTimeout(
|
|
||||||
QuicTimerCallback* callback,
|
|
||||||
std::chrono::microseconds timeout) {
|
|
||||||
CHECK(!callback_)
|
|
||||||
<< "Another callback is already scheduled on this QuicTimer";
|
|
||||||
callback_ = callback;
|
|
||||||
QuicEventBase::setImplHandle(callback_, this);
|
|
||||||
|
|
||||||
double seconds = timeout.count() / 10000.;
|
|
||||||
ev_timer_init(
|
|
||||||
&timeoutWatcher_,
|
|
||||||
libEvTimeoutCallback,
|
|
||||||
seconds /* after */,
|
|
||||||
0. /* repeat */);
|
|
||||||
ev_timer_start(ev_loop_, &timeoutWatcher_);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LibevQuicTimer::isTimerCallbackScheduled(
|
|
||||||
QuicTimerCallback* callback) const {
|
|
||||||
return callback == callback_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LibevQuicTimer::cancelTimeout(QuicTimerCallback* callback) {
|
|
||||||
CHECK_EQ(callback_, callback);
|
|
||||||
QuicEventBase::setImplHandle(callback_, nullptr);
|
|
||||||
ev_timer_stop(ev_loop_, &timeoutWatcher_);
|
|
||||||
callback_ = nullptr;
|
|
||||||
if (selfOwned_) {
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LibevQuicTimer::timeoutExpired() noexcept {
|
|
||||||
CHECK(callback_);
|
|
||||||
QuicEventBase::setImplHandle(callback_, nullptr);
|
|
||||||
callback_->timeoutExpired();
|
|
||||||
ev_timer_stop(ev_loop_, &timeoutWatcher_);
|
|
||||||
callback_ = nullptr;
|
|
||||||
if (selfOwned_) {
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // namespace quic
|
|
@@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the MIT license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <quic/common/events/QuicEventBase.h>
|
|
||||||
#include <quic/common/events/QuicTimer.h>
|
|
||||||
|
|
||||||
#include <ev.h>
|
|
||||||
|
|
||||||
namespace quic {
|
|
||||||
|
|
||||||
class LibevQuicTimer : public QuicTimer,
|
|
||||||
public QuicTimerCallback::TimerCallbackImpl {
|
|
||||||
public:
|
|
||||||
explicit LibevQuicTimer(struct ev_loop* libevLoop, bool selfOwned = false);
|
|
||||||
~LibevQuicTimer() override;
|
|
||||||
|
|
||||||
void scheduleTimeout(
|
|
||||||
QuicTimerCallback* callback,
|
|
||||||
std::chrono::microseconds timeout) override;
|
|
||||||
|
|
||||||
bool isTimerCallbackScheduled(QuicTimerCallback* callback) const override;
|
|
||||||
|
|
||||||
void cancelTimeout(QuicTimerCallback* callback) override;
|
|
||||||
|
|
||||||
[[nodiscard]] std::chrono::microseconds getTickInterval() const override {
|
|
||||||
LOG(WARNING) << __func__ << " is not implemented in LibevQuicTimer";
|
|
||||||
return std::chrono::microseconds(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void timeoutExpired() noexcept;
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct ev_loop* ev_loop_{nullptr};
|
|
||||||
ev_timer timeoutWatcher_;
|
|
||||||
bool selfOwned_{false};
|
|
||||||
|
|
||||||
QuicTimerCallback* callback_{nullptr};
|
|
||||||
};
|
|
||||||
} // namespace quic
|
|
@@ -20,9 +20,27 @@ class QuicEventBaseLoopCallback {
|
|||||||
public:
|
public:
|
||||||
friend class QuicEventBase;
|
friend class QuicEventBase;
|
||||||
|
|
||||||
virtual ~QuicEventBaseLoopCallback() = default;
|
virtual ~QuicEventBaseLoopCallback() {
|
||||||
|
if (implHandle) {
|
||||||
|
implHandle->cancelImpl();
|
||||||
|
delete implHandle;
|
||||||
|
}
|
||||||
|
}
|
||||||
virtual void runLoopCallback() noexcept = 0;
|
virtual void runLoopCallback() noexcept = 0;
|
||||||
class LoopCallbackImpl {};
|
void cancelLoopCallback() noexcept {
|
||||||
|
if (implHandle) {
|
||||||
|
implHandle->cancelImpl();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[[nodiscard]] bool isLoopCallbackScheduled() const noexcept {
|
||||||
|
return implHandle ? implHandle->isScheduledImpl() : false;
|
||||||
|
}
|
||||||
|
class LoopCallbackImpl {
|
||||||
|
public:
|
||||||
|
virtual ~LoopCallbackImpl() = default;
|
||||||
|
virtual void cancelImpl() noexcept = 0;
|
||||||
|
[[nodiscard]] virtual bool isScheduledImpl() const noexcept = 0;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LoopCallbackImpl* implHandle{nullptr};
|
LoopCallbackImpl* implHandle{nullptr};
|
||||||
@@ -31,7 +49,12 @@ class QuicEventBaseLoopCallback {
|
|||||||
class QuicTimerCallback {
|
class QuicTimerCallback {
|
||||||
public:
|
public:
|
||||||
friend class QuicEventBase;
|
friend class QuicEventBase;
|
||||||
virtual ~QuicTimerCallback() = default;
|
virtual ~QuicTimerCallback() {
|
||||||
|
if (implHandle) {
|
||||||
|
implHandle->cancelImpl();
|
||||||
|
delete implHandle;
|
||||||
|
}
|
||||||
|
}
|
||||||
virtual void timeoutExpired() noexcept = 0;
|
virtual void timeoutExpired() noexcept = 0;
|
||||||
/// This callback was canceled. The default implementation is to just
|
/// This callback was canceled. The default implementation is to just
|
||||||
/// proxy to `timeoutExpired` but if you care about the difference between
|
/// proxy to `timeoutExpired` but if you care about the difference between
|
||||||
@@ -39,7 +62,33 @@ class QuicTimerCallback {
|
|||||||
virtual void callbackCanceled() noexcept {
|
virtual void callbackCanceled() noexcept {
|
||||||
timeoutExpired();
|
timeoutExpired();
|
||||||
}
|
}
|
||||||
class TimerCallbackImpl {};
|
|
||||||
|
void cancelTimerCallback() noexcept {
|
||||||
|
if (implHandle) {
|
||||||
|
implHandle->cancelImpl();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool isTimerCallbackScheduled() const noexcept {
|
||||||
|
return implHandle ? implHandle->isScheduledImpl() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] std::chrono::milliseconds getTimerCallbackTimeRemaining()
|
||||||
|
const noexcept {
|
||||||
|
if (!implHandle) {
|
||||||
|
return std::chrono::milliseconds(0);
|
||||||
|
}
|
||||||
|
return implHandle->getTimeRemainingImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
class TimerCallbackImpl {
|
||||||
|
public:
|
||||||
|
virtual ~TimerCallbackImpl() = default;
|
||||||
|
virtual void cancelImpl() noexcept = 0;
|
||||||
|
[[nodiscard]] virtual bool isScheduledImpl() const noexcept = 0;
|
||||||
|
[[nodiscard]] virtual std::chrono::milliseconds getTimeRemainingImpl()
|
||||||
|
const noexcept = 0;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TimerCallbackImpl* implHandle{nullptr};
|
TimerCallbackImpl* implHandle{nullptr};
|
||||||
@@ -82,18 +131,6 @@ class QuicEventBase {
|
|||||||
QuicTimerCallback* callback,
|
QuicTimerCallback* callback,
|
||||||
std::chrono::microseconds timeout) = 0;
|
std::chrono::microseconds timeout) = 0;
|
||||||
|
|
||||||
virtual void cancelLoopCallback(QuicEventBaseLoopCallback* callback) = 0;
|
|
||||||
|
|
||||||
virtual bool isTimeoutScheduled(QuicTimerCallback* callback) const = 0;
|
|
||||||
|
|
||||||
virtual std::chrono::milliseconds getTimeoutTimeRemaining(
|
|
||||||
QuicTimerCallback* callback) const = 0;
|
|
||||||
|
|
||||||
virtual void cancelTimeout(QuicTimerCallback* callback) = 0;
|
|
||||||
|
|
||||||
virtual bool isLoopCallbackScheduled(
|
|
||||||
QuicEventBaseLoopCallback* callback) const = 0;
|
|
||||||
|
|
||||||
virtual bool loopOnce(int flags = 0) = 0;
|
virtual bool loopOnce(int flags = 0) = 0;
|
||||||
|
|
||||||
virtual bool loop() = 0;
|
virtual bool loop() = 0;
|
||||||
|
@@ -26,10 +26,6 @@ class QuicTimer : public folly::DelayedDestruction {
|
|||||||
virtual void scheduleTimeout(
|
virtual void scheduleTimeout(
|
||||||
QuicTimerCallback* callback,
|
QuicTimerCallback* callback,
|
||||||
std::chrono::microseconds timeout) = 0;
|
std::chrono::microseconds timeout) = 0;
|
||||||
|
|
||||||
virtual bool isTimerCallbackScheduled(QuicTimerCallback* callback) const = 0;
|
|
||||||
|
|
||||||
virtual void cancelTimeout(QuicTimerCallback* callback) = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace quic
|
} // namespace quic
|
||||||
|
@@ -27,43 +27,19 @@ void TimerFDQuicTimer::scheduleTimeout(
|
|||||||
// There is no callback. Nothing to schedule.
|
// There is no callback. Nothing to schedule.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (QuicEventBase::getImplHandle(callback)) {
|
auto wrapper = static_cast<TimerCallbackWrapper*>(
|
||||||
// This callback is already scheduled.
|
QuicEventBase::getImplHandle(callback));
|
||||||
return;
|
if (wrapper == nullptr) {
|
||||||
|
// This is the first time this timer callback is getting scheduled. Create a
|
||||||
|
// wrapper for it.
|
||||||
|
wrapper = new TimerCallbackWrapper(callback);
|
||||||
|
QuicEventBase::setImplHandle(callback, wrapper);
|
||||||
}
|
}
|
||||||
auto* wrapper = new TimerCallbackWrapper(callback, this);
|
|
||||||
timerCallbackWrappers_.push_back(*wrapper);
|
|
||||||
QuicEventBase::setImplHandle(callback, wrapper);
|
|
||||||
return wheelTimer_->scheduleTimeout(wrapper, timeout);
|
return wheelTimer_->scheduleTimeout(wrapper, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TimerFDQuicTimer::isTimerCallbackScheduled(
|
|
||||||
QuicTimerCallback* callback) const {
|
|
||||||
if (!callback || !QuicEventBase::getImplHandle(callback)) {
|
|
||||||
// There is no wrapper. Nothing is scheduled.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
auto wrapper = static_cast<TimerCallbackWrapper*>(
|
|
||||||
QuicEventBase::getImplHandle(callback));
|
|
||||||
return wrapper->isScheduled();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TimerFDQuicTimer::cancelTimeout(QuicTimerCallback* callback) {
|
|
||||||
if (!callback || !QuicEventBase::getImplHandle(callback)) {
|
|
||||||
// There is no wrapper. Nothing to cancel.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto wrapper = static_cast<TimerCallbackWrapper*>(
|
|
||||||
QuicEventBase::getImplHandle(callback));
|
|
||||||
wrapper->cancelTimeout();
|
|
||||||
unregisterCallbackInternal(callback);
|
|
||||||
delete wrapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
TimerFDQuicTimer::~TimerFDQuicTimer() {
|
TimerFDQuicTimer::~TimerFDQuicTimer() {
|
||||||
// Resetting the wheel timer cancels all pending timeouts which clears the
|
// Resetting the wheel timer cancels all pending timeouts.
|
||||||
// wrappers.
|
|
||||||
wheelTimer_.reset();
|
wheelTimer_.reset();
|
||||||
CHECK(timerCallbackWrappers_.empty());
|
|
||||||
}
|
}
|
||||||
} // namespace quic
|
} // namespace quic
|
||||||
|
@@ -9,7 +9,6 @@
|
|||||||
|
|
||||||
#include <quic/common/events/QuicTimer.h>
|
#include <quic/common/events/QuicTimer.h>
|
||||||
|
|
||||||
#include <folly/IntrusiveList.h>
|
|
||||||
#include <folly/experimental/STTimerFDTimeoutManager.h>
|
#include <folly/experimental/STTimerFDTimeoutManager.h>
|
||||||
#include <folly/io/async/HHWheelTimer.h>
|
#include <folly/io/async/HHWheelTimer.h>
|
||||||
|
|
||||||
@@ -28,48 +27,46 @@ class TimerFDQuicTimer : public QuicTimer {
|
|||||||
QuicTimerCallback* callback,
|
QuicTimerCallback* callback,
|
||||||
std::chrono::microseconds timeout) override;
|
std::chrono::microseconds timeout) override;
|
||||||
|
|
||||||
bool isTimerCallbackScheduled(QuicTimerCallback* callback) const override;
|
|
||||||
|
|
||||||
void cancelTimeout(QuicTimerCallback* callback) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void unregisterCallbackInternal(QuicTimerCallback* callback) {
|
|
||||||
QuicEventBase::setImplHandle(callback, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
class TimerCallbackWrapper : public folly::HHWheelTimerHighRes::Callback,
|
class TimerCallbackWrapper : public folly::HHWheelTimerHighRes::Callback,
|
||||||
QuicTimerCallback::TimerCallbackImpl {
|
QuicTimerCallback::TimerCallbackImpl {
|
||||||
public:
|
public:
|
||||||
explicit TimerCallbackWrapper(
|
explicit TimerCallbackWrapper(QuicTimerCallback* callback) {
|
||||||
QuicTimerCallback* callback,
|
|
||||||
TimerFDQuicTimer* parentTimer) {
|
|
||||||
parentTimer_ = parentTimer;
|
|
||||||
callback_ = callback;
|
callback_ = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend class TimerFDQuicTimer;
|
friend class TimerFDQuicTimer;
|
||||||
|
|
||||||
void timeoutExpired() noexcept override {
|
void timeoutExpired() noexcept override {
|
||||||
parentTimer_->unregisterCallbackInternal(callback_);
|
|
||||||
callback_->timeoutExpired();
|
callback_->timeoutExpired();
|
||||||
delete this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void callbackCanceled() noexcept override {
|
void callbackCanceled() noexcept override {
|
||||||
parentTimer_->unregisterCallbackInternal(callback_);
|
|
||||||
callback_->callbackCanceled();
|
callback_->callbackCanceled();
|
||||||
delete this;
|
}
|
||||||
|
|
||||||
|
// QuicTimerCallback::TimerCallbackImpl
|
||||||
|
void cancelImpl() noexcept override {
|
||||||
|
folly::HHWheelTimerHighRes::Callback::cancelTimeout();
|
||||||
|
}
|
||||||
|
|
||||||
|
// QuicTimerCallback::TimerCallbackImpl
|
||||||
|
[[nodiscard]] bool isScheduledImpl() const noexcept override {
|
||||||
|
return folly::HHWheelTimerHighRes::Callback::isScheduled();
|
||||||
|
}
|
||||||
|
|
||||||
|
// QuicTimerCallback::TimerCallbackImpl
|
||||||
|
[[nodiscard]] std::chrono::milliseconds getTimeRemainingImpl()
|
||||||
|
const noexcept override {
|
||||||
|
// TODO parametrize this type if it's used anywhere outside of tests
|
||||||
|
return std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||||
|
folly::HHWheelTimerHighRes::Callback::getTimeRemaining());
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TimerFDQuicTimer* parentTimer_;
|
|
||||||
QuicTimerCallback* callback_;
|
QuicTimerCallback* callback_;
|
||||||
folly::IntrusiveListHook listHook_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
folly::IntrusiveList<TimerCallbackWrapper, &TimerCallbackWrapper::listHook_>
|
|
||||||
timerCallbackWrappers_;
|
|
||||||
|
|
||||||
folly::STTimerFDTimeoutManager timeoutMgr_;
|
folly::STTimerFDTimeoutManager timeoutMgr_;
|
||||||
folly::HHWheelTimerHighRes::UniquePtr wheelTimer_;
|
folly::HHWheelTimerHighRes::UniquePtr wheelTimer_;
|
||||||
};
|
};
|
||||||
|
@@ -217,20 +217,20 @@ TEST(FunctionLooperTest, KeepPacing) {
|
|||||||
EXPECT_EQ(1, count);
|
EXPECT_EQ(1, count);
|
||||||
EXPECT_TRUE(looper->isPacingScheduled());
|
EXPECT_TRUE(looper->isPacingScheduled());
|
||||||
|
|
||||||
pacingTimer->cancelTimeout(looper.get());
|
looper->cancelTimerCallback();
|
||||||
EXPECT_FALSE(looper->isPacingScheduled());
|
EXPECT_FALSE(looper->isPacingScheduled());
|
||||||
looper->timeoutExpired();
|
looper->timeoutExpired();
|
||||||
EXPECT_EQ(2, count);
|
EXPECT_EQ(2, count);
|
||||||
EXPECT_TRUE(looper->isPacingScheduled());
|
EXPECT_TRUE(looper->isPacingScheduled());
|
||||||
|
|
||||||
pacingTimer->cancelTimeout(looper.get());
|
looper->cancelTimerCallback();
|
||||||
EXPECT_FALSE(looper->isPacingScheduled());
|
EXPECT_FALSE(looper->isPacingScheduled());
|
||||||
looper->timeoutExpired();
|
looper->timeoutExpired();
|
||||||
EXPECT_EQ(3, count);
|
EXPECT_EQ(3, count);
|
||||||
EXPECT_TRUE(looper->isPacingScheduled());
|
EXPECT_TRUE(looper->isPacingScheduled());
|
||||||
|
|
||||||
stopPacing = true;
|
stopPacing = true;
|
||||||
pacingTimer->cancelTimeout(looper.get());
|
looper->cancelTimerCallback();
|
||||||
EXPECT_FALSE(looper->isPacingScheduled());
|
EXPECT_FALSE(looper->isPacingScheduled());
|
||||||
looper->timeoutExpired();
|
looper->timeoutExpired();
|
||||||
EXPECT_EQ(4, count);
|
EXPECT_EQ(4, count);
|
||||||
|
@@ -1199,8 +1199,8 @@ TEST_F(QuicClientTransportTest, HappyEyeballsWithSingleV4Address) {
|
|||||||
EXPECT_FALSE(conn.happyEyeballsState.finished);
|
EXPECT_FALSE(conn.happyEyeballsState.finished);
|
||||||
EXPECT_FALSE(conn.peerAddress.isInitialized());
|
EXPECT_FALSE(conn.peerAddress.isInitialized());
|
||||||
client->start(&clientConnSetupCallback, &clientConnCallback);
|
client->start(&clientConnSetupCallback, &clientConnCallback);
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(
|
EXPECT_FALSE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
EXPECT_TRUE(conn.happyEyeballsState.finished);
|
EXPECT_TRUE(conn.happyEyeballsState.finished);
|
||||||
EXPECT_EQ(conn.peerAddress, serverAddr);
|
EXPECT_EQ(conn.peerAddress, serverAddr);
|
||||||
}
|
}
|
||||||
@@ -1219,8 +1219,8 @@ TEST_F(QuicClientTransportTest, HappyEyeballsWithSingleV6Address) {
|
|||||||
EXPECT_FALSE(conn.happyEyeballsState.finished);
|
EXPECT_FALSE(conn.happyEyeballsState.finished);
|
||||||
EXPECT_FALSE(conn.peerAddress.isInitialized());
|
EXPECT_FALSE(conn.peerAddress.isInitialized());
|
||||||
client->start(&clientConnSetupCallback, &clientConnCallback);
|
client->start(&clientConnSetupCallback, &clientConnCallback);
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(
|
EXPECT_FALSE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
EXPECT_TRUE(conn.happyEyeballsState.finished);
|
EXPECT_TRUE(conn.happyEyeballsState.finished);
|
||||||
EXPECT_EQ(conn.peerAddress, serverAddrV6);
|
EXPECT_EQ(conn.peerAddress, serverAddrV6);
|
||||||
}
|
}
|
||||||
@@ -1231,7 +1231,7 @@ TEST_F(QuicClientTransportTest, IdleTimerResetOnWritingFirstData) {
|
|||||||
client->start(&clientConnSetupCallback, &clientConnCallback);
|
client->start(&clientConnSetupCallback, &clientConnCallback);
|
||||||
loopForWrites();
|
loopForWrites();
|
||||||
ASSERT_FALSE(client->getConn().receivedNewPacketBeforeWrite);
|
ASSERT_FALSE(client->getConn().receivedNewPacketBeforeWrite);
|
||||||
ASSERT_TRUE(qEvb_->isTimeoutScheduled(&client->idleTimeout()));
|
ASSERT_TRUE(client->idleTimeout().isTimerCallbackScheduled());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(QuicClientTransportTest, SetQLoggerDcid) {
|
TEST_F(QuicClientTransportTest, SetQLoggerDcid) {
|
||||||
@@ -1393,8 +1393,8 @@ class QuicClientTransportHappyEyeballsTest
|
|||||||
|
|
||||||
EXPECT_EQ(conn.peerAddress, firstAddress);
|
EXPECT_EQ(conn.peerAddress, firstAddress);
|
||||||
EXPECT_EQ(conn.happyEyeballsState.secondPeerAddress, secondAddress);
|
EXPECT_EQ(conn.happyEyeballsState.secondPeerAddress, secondAddress);
|
||||||
EXPECT_TRUE(qEvb_->isTimeoutScheduled(
|
EXPECT_TRUE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
EXPECT_EQ(socketWrites.size(), 1);
|
EXPECT_EQ(socketWrites.size(), 1);
|
||||||
EXPECT_TRUE(
|
EXPECT_TRUE(
|
||||||
verifyLongHeader(*socketWrites.at(0), LongHeader::Types::Initial));
|
verifyLongHeader(*socketWrites.at(0), LongHeader::Types::Initial));
|
||||||
@@ -1414,8 +1414,8 @@ class QuicClientTransportHappyEyeballsTest
|
|||||||
} else {
|
} else {
|
||||||
performFakeHandshake(firstAddress);
|
performFakeHandshake(firstAddress);
|
||||||
}
|
}
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(
|
EXPECT_FALSE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
EXPECT_TRUE(client->getConn().happyEyeballsState.finished);
|
EXPECT_TRUE(client->getConn().happyEyeballsState.finished);
|
||||||
EXPECT_EQ(client->getConn().originalPeerAddress, firstAddress);
|
EXPECT_EQ(client->getConn().originalPeerAddress, firstAddress);
|
||||||
EXPECT_EQ(client->getConn().peerAddress, firstAddress);
|
EXPECT_EQ(client->getConn().peerAddress, firstAddress);
|
||||||
@@ -1440,8 +1440,8 @@ class QuicClientTransportHappyEyeballsTest
|
|||||||
|
|
||||||
EXPECT_EQ(conn.peerAddress, firstAddress);
|
EXPECT_EQ(conn.peerAddress, firstAddress);
|
||||||
EXPECT_EQ(conn.happyEyeballsState.secondPeerAddress, secondAddress);
|
EXPECT_EQ(conn.happyEyeballsState.secondPeerAddress, secondAddress);
|
||||||
EXPECT_TRUE(qEvb_->isTimeoutScheduled(
|
EXPECT_TRUE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
EXPECT_EQ(socketWrites.size(), 1);
|
EXPECT_EQ(socketWrites.size(), 1);
|
||||||
EXPECT_TRUE(
|
EXPECT_TRUE(
|
||||||
verifyLongHeader(*socketWrites.at(0), LongHeader::Types::Initial));
|
verifyLongHeader(*socketWrites.at(0), LongHeader::Types::Initial));
|
||||||
@@ -1450,11 +1450,11 @@ class QuicClientTransportHappyEyeballsTest
|
|||||||
|
|
||||||
// Manually expire conn attempt timeout
|
// Manually expire conn attempt timeout
|
||||||
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
||||||
qEvb_->cancelTimeout(&client->happyEyeballsConnAttemptDelayTimeout());
|
client->happyEyeballsConnAttemptDelayTimeout().cancelTimerCallback();
|
||||||
client->happyEyeballsConnAttemptDelayTimeout().timeoutExpired();
|
client->happyEyeballsConnAttemptDelayTimeout().timeoutExpired();
|
||||||
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(
|
EXPECT_FALSE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
|
|
||||||
// Manually expire loss timeout to trigger write to both first and second
|
// Manually expire loss timeout to trigger write to both first and second
|
||||||
// socket
|
// socket
|
||||||
@@ -1465,7 +1465,7 @@ class QuicClientTransportHappyEyeballsTest
|
|||||||
return buf->computeChainDataLength();
|
return buf->computeChainDataLength();
|
||||||
}));
|
}));
|
||||||
EXPECT_CALL(*secondSock, write(secondAddress, _));
|
EXPECT_CALL(*secondSock, write(secondAddress, _));
|
||||||
qEvb_->cancelTimeout(&client->lossTimeout());
|
client->lossTimeout().cancelTimerCallback();
|
||||||
client->lossTimeout().timeoutExpired();
|
client->lossTimeout().timeoutExpired();
|
||||||
EXPECT_EQ(socketWrites.size(), 1);
|
EXPECT_EQ(socketWrites.size(), 1);
|
||||||
EXPECT_TRUE(
|
EXPECT_TRUE(
|
||||||
@@ -1517,8 +1517,8 @@ class QuicClientTransportHappyEyeballsTest
|
|||||||
setConnectionIds();
|
setConnectionIds();
|
||||||
EXPECT_EQ(conn.peerAddress, firstAddress);
|
EXPECT_EQ(conn.peerAddress, firstAddress);
|
||||||
EXPECT_EQ(conn.happyEyeballsState.secondPeerAddress, secondAddress);
|
EXPECT_EQ(conn.happyEyeballsState.secondPeerAddress, secondAddress);
|
||||||
EXPECT_TRUE(qEvb_->isTimeoutScheduled(
|
EXPECT_TRUE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
EXPECT_EQ(socketWrites.size(), 1);
|
EXPECT_EQ(socketWrites.size(), 1);
|
||||||
|
|
||||||
EXPECT_TRUE(
|
EXPECT_TRUE(
|
||||||
@@ -1528,11 +1528,11 @@ class QuicClientTransportHappyEyeballsTest
|
|||||||
|
|
||||||
// Manually expire conn attempt timeout
|
// Manually expire conn attempt timeout
|
||||||
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
||||||
qEvb_->cancelTimeout(&client->happyEyeballsConnAttemptDelayTimeout());
|
client->happyEyeballsConnAttemptDelayTimeout().cancelTimerCallback();
|
||||||
client->happyEyeballsConnAttemptDelayTimeout().timeoutExpired();
|
client->happyEyeballsConnAttemptDelayTimeout().timeoutExpired();
|
||||||
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(
|
EXPECT_FALSE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
|
|
||||||
// Manually expire loss timeout to trigger write to both first and second
|
// Manually expire loss timeout to trigger write to both first and second
|
||||||
// socket
|
// socket
|
||||||
@@ -1543,7 +1543,7 @@ class QuicClientTransportHappyEyeballsTest
|
|||||||
socketWrites.push_back(buf->clone());
|
socketWrites.push_back(buf->clone());
|
||||||
return buf->computeChainDataLength();
|
return buf->computeChainDataLength();
|
||||||
}));
|
}));
|
||||||
qEvb_->cancelTimeout(&client->lossTimeout());
|
client->lossTimeout().cancelTimerCallback();
|
||||||
client->lossTimeout().timeoutExpired();
|
client->lossTimeout().timeoutExpired();
|
||||||
EXPECT_EQ(socketWrites.size(), 1);
|
EXPECT_EQ(socketWrites.size(), 1);
|
||||||
EXPECT_TRUE(
|
EXPECT_TRUE(
|
||||||
@@ -1591,8 +1591,8 @@ class QuicClientTransportHappyEyeballsTest
|
|||||||
client->start(&clientConnSetupCallback, &clientConnCallback);
|
client->start(&clientConnSetupCallback, &clientConnCallback);
|
||||||
EXPECT_EQ(conn.peerAddress, firstAddress);
|
EXPECT_EQ(conn.peerAddress, firstAddress);
|
||||||
EXPECT_EQ(conn.happyEyeballsState.secondPeerAddress, secondAddress);
|
EXPECT_EQ(conn.happyEyeballsState.secondPeerAddress, secondAddress);
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(
|
EXPECT_FALSE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
||||||
EXPECT_TRUE(conn.happyEyeballsState.finished);
|
EXPECT_TRUE(conn.happyEyeballsState.finished);
|
||||||
}
|
}
|
||||||
@@ -1612,12 +1612,12 @@ class QuicClientTransportHappyEyeballsTest
|
|||||||
// Continue trying first socket
|
// Continue trying first socket
|
||||||
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToFirstSocket);
|
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToFirstSocket);
|
||||||
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(
|
EXPECT_FALSE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
|
|
||||||
EXPECT_CALL(*sock, write(firstAddress, _));
|
EXPECT_CALL(*sock, write(firstAddress, _));
|
||||||
EXPECT_CALL(*secondSock, write(secondAddress, _));
|
EXPECT_CALL(*secondSock, write(secondAddress, _));
|
||||||
qEvb_->cancelTimeout(&client->lossTimeout());
|
client->lossTimeout().cancelTimerCallback();
|
||||||
client->lossTimeout().timeoutExpired();
|
client->lossTimeout().timeoutExpired();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1638,12 +1638,12 @@ class QuicClientTransportHappyEyeballsTest
|
|||||||
// Give up first socket
|
// Give up first socket
|
||||||
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToFirstSocket);
|
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToFirstSocket);
|
||||||
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(
|
EXPECT_FALSE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
|
|
||||||
EXPECT_CALL(*sock, write(_, _)).Times(0);
|
EXPECT_CALL(*sock, write(_, _)).Times(0);
|
||||||
EXPECT_CALL(*secondSock, write(secondAddress, _));
|
EXPECT_CALL(*secondSock, write(secondAddress, _));
|
||||||
qEvb_->cancelTimeout(&client->lossTimeout());
|
client->lossTimeout().cancelTimerCallback();
|
||||||
client->lossTimeout().timeoutExpired();
|
client->lossTimeout().timeoutExpired();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1674,12 +1674,12 @@ class QuicClientTransportHappyEyeballsTest
|
|||||||
client->errMessage(cmsgbuf.hdr);
|
client->errMessage(cmsgbuf.hdr);
|
||||||
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToFirstSocket);
|
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToFirstSocket);
|
||||||
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(
|
EXPECT_FALSE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
|
|
||||||
EXPECT_CALL(*sock, write(_, _)).Times(0);
|
EXPECT_CALL(*sock, write(_, _)).Times(0);
|
||||||
EXPECT_CALL(*secondSock, write(secondAddress, _));
|
EXPECT_CALL(*secondSock, write(secondAddress, _));
|
||||||
qEvb_->cancelTimeout(&client->lossTimeout());
|
client->lossTimeout().cancelTimerCallback();
|
||||||
client->lossTimeout().timeoutExpired();
|
client->lossTimeout().timeoutExpired();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -1694,23 +1694,23 @@ class QuicClientTransportHappyEyeballsTest
|
|||||||
client->start(&clientConnSetupCallback, &clientConnCallback);
|
client->start(&clientConnSetupCallback, &clientConnCallback);
|
||||||
EXPECT_EQ(conn.peerAddress, firstAddress);
|
EXPECT_EQ(conn.peerAddress, firstAddress);
|
||||||
EXPECT_EQ(conn.happyEyeballsState.secondPeerAddress, secondAddress);
|
EXPECT_EQ(conn.happyEyeballsState.secondPeerAddress, secondAddress);
|
||||||
EXPECT_TRUE(qEvb_->isTimeoutScheduled(
|
EXPECT_TRUE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
|
|
||||||
// Manually expire conn attempt timeout
|
// Manually expire conn attempt timeout
|
||||||
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
||||||
qEvb_->cancelTimeout(&client->happyEyeballsConnAttemptDelayTimeout());
|
client->happyEyeballsConnAttemptDelayTimeout().cancelTimerCallback();
|
||||||
client->happyEyeballsConnAttemptDelayTimeout().timeoutExpired();
|
client->happyEyeballsConnAttemptDelayTimeout().timeoutExpired();
|
||||||
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(
|
EXPECT_FALSE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
|
|
||||||
// Manually expire loss timeout to trigger write to both first and second
|
// Manually expire loss timeout to trigger write to both first and second
|
||||||
// socket
|
// socket
|
||||||
EXPECT_CALL(*sock, write(firstAddress, _))
|
EXPECT_CALL(*sock, write(firstAddress, _))
|
||||||
.WillOnce(SetErrnoAndReturn(EAGAIN, -1));
|
.WillOnce(SetErrnoAndReturn(EAGAIN, -1));
|
||||||
EXPECT_CALL(*secondSock, write(secondAddress, _));
|
EXPECT_CALL(*secondSock, write(secondAddress, _));
|
||||||
qEvb_->cancelTimeout(&client->lossTimeout());
|
client->lossTimeout().cancelTimerCallback();
|
||||||
client->lossTimeout().timeoutExpired();
|
client->lossTimeout().timeoutExpired();
|
||||||
|
|
||||||
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToFirstSocket);
|
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToFirstSocket);
|
||||||
@@ -1718,7 +1718,7 @@ class QuicClientTransportHappyEyeballsTest
|
|||||||
|
|
||||||
EXPECT_CALL(*sock, write(firstAddress, _)).Times(1);
|
EXPECT_CALL(*sock, write(firstAddress, _)).Times(1);
|
||||||
EXPECT_CALL(*secondSock, write(secondAddress, _)).Times(1);
|
EXPECT_CALL(*secondSock, write(secondAddress, _)).Times(1);
|
||||||
qEvb_->cancelTimeout(&client->lossTimeout());
|
client->lossTimeout().cancelTimerCallback();
|
||||||
client->lossTimeout().timeoutExpired();
|
client->lossTimeout().timeoutExpired();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1732,16 +1732,16 @@ class QuicClientTransportHappyEyeballsTest
|
|||||||
client->start(&clientConnSetupCallback, &clientConnCallback);
|
client->start(&clientConnSetupCallback, &clientConnCallback);
|
||||||
EXPECT_EQ(conn.peerAddress, firstAddress);
|
EXPECT_EQ(conn.peerAddress, firstAddress);
|
||||||
EXPECT_EQ(conn.happyEyeballsState.secondPeerAddress, secondAddress);
|
EXPECT_EQ(conn.happyEyeballsState.secondPeerAddress, secondAddress);
|
||||||
EXPECT_TRUE(qEvb_->isTimeoutScheduled(
|
EXPECT_TRUE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
|
|
||||||
// Manually expire conn attempt timeout
|
// Manually expire conn attempt timeout
|
||||||
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
||||||
qEvb_->cancelTimeout(&client->happyEyeballsConnAttemptDelayTimeout());
|
client->happyEyeballsConnAttemptDelayTimeout().cancelTimerCallback();
|
||||||
client->happyEyeballsConnAttemptDelayTimeout().timeoutExpired();
|
client->happyEyeballsConnAttemptDelayTimeout().timeoutExpired();
|
||||||
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(
|
EXPECT_FALSE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
|
|
||||||
// Manually expire loss timeout to trigger write to both first and second
|
// Manually expire loss timeout to trigger write to both first and second
|
||||||
// socket
|
// socket
|
||||||
@@ -1752,7 +1752,7 @@ class QuicClientTransportHappyEyeballsTest
|
|||||||
EXPECT_CALL(*sock, pauseRead()).Times(2);
|
EXPECT_CALL(*sock, pauseRead()).Times(2);
|
||||||
EXPECT_CALL(*sock, close()).Times(1);
|
EXPECT_CALL(*sock, close()).Times(1);
|
||||||
EXPECT_CALL(*secondSock, write(secondAddress, _));
|
EXPECT_CALL(*secondSock, write(secondAddress, _));
|
||||||
qEvb_->cancelTimeout(&client->lossTimeout());
|
client->lossTimeout().cancelTimerCallback();
|
||||||
client->lossTimeout().timeoutExpired();
|
client->lossTimeout().timeoutExpired();
|
||||||
|
|
||||||
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToFirstSocket);
|
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToFirstSocket);
|
||||||
@@ -1760,7 +1760,7 @@ class QuicClientTransportHappyEyeballsTest
|
|||||||
|
|
||||||
EXPECT_CALL(*sock, write(_, _)).Times(0);
|
EXPECT_CALL(*sock, write(_, _)).Times(0);
|
||||||
EXPECT_CALL(*secondSock, write(secondAddress, _)).Times(1);
|
EXPECT_CALL(*secondSock, write(secondAddress, _)).Times(1);
|
||||||
qEvb_->cancelTimeout(&client->lossTimeout());
|
client->lossTimeout().cancelTimerCallback();
|
||||||
client->lossTimeout().timeoutExpired();
|
client->lossTimeout().timeoutExpired();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1775,16 +1775,16 @@ class QuicClientTransportHappyEyeballsTest
|
|||||||
client->start(&clientConnSetupCallback, &clientConnCallback);
|
client->start(&clientConnSetupCallback, &clientConnCallback);
|
||||||
EXPECT_EQ(conn.peerAddress, firstAddress);
|
EXPECT_EQ(conn.peerAddress, firstAddress);
|
||||||
EXPECT_EQ(conn.happyEyeballsState.secondPeerAddress, secondAddress);
|
EXPECT_EQ(conn.happyEyeballsState.secondPeerAddress, secondAddress);
|
||||||
EXPECT_TRUE(qEvb_->isTimeoutScheduled(
|
EXPECT_TRUE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
|
|
||||||
// Manually expire conn attempt timeout
|
// Manually expire conn attempt timeout
|
||||||
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
||||||
qEvb_->cancelTimeout(&client->happyEyeballsConnAttemptDelayTimeout());
|
client->happyEyeballsConnAttemptDelayTimeout().cancelTimerCallback();
|
||||||
client->happyEyeballsConnAttemptDelayTimeout().timeoutExpired();
|
client->happyEyeballsConnAttemptDelayTimeout().timeoutExpired();
|
||||||
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(
|
EXPECT_FALSE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
|
|
||||||
EXPECT_CALL(*sock, pauseRead()).Times(2);
|
EXPECT_CALL(*sock, pauseRead()).Times(2);
|
||||||
EXPECT_CALL(*sock, close()).Times(1);
|
EXPECT_CALL(*sock, close()).Times(1);
|
||||||
@@ -1806,7 +1806,7 @@ class QuicClientTransportHappyEyeballsTest
|
|||||||
|
|
||||||
EXPECT_CALL(*sock, write(_, _)).Times(0);
|
EXPECT_CALL(*sock, write(_, _)).Times(0);
|
||||||
EXPECT_CALL(*secondSock, write(secondAddress, _)).Times(1);
|
EXPECT_CALL(*secondSock, write(secondAddress, _)).Times(1);
|
||||||
qEvb_->cancelTimeout(&client->lossTimeout());
|
client->lossTimeout().cancelTimerCallback();
|
||||||
client->lossTimeout().timeoutExpired();
|
client->lossTimeout().timeoutExpired();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -1821,23 +1821,23 @@ class QuicClientTransportHappyEyeballsTest
|
|||||||
client->start(&clientConnSetupCallback, &clientConnCallback);
|
client->start(&clientConnSetupCallback, &clientConnCallback);
|
||||||
EXPECT_EQ(conn.peerAddress, firstAddress);
|
EXPECT_EQ(conn.peerAddress, firstAddress);
|
||||||
EXPECT_EQ(conn.happyEyeballsState.secondPeerAddress, secondAddress);
|
EXPECT_EQ(conn.happyEyeballsState.secondPeerAddress, secondAddress);
|
||||||
EXPECT_TRUE(qEvb_->isTimeoutScheduled(
|
EXPECT_TRUE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
|
|
||||||
// Manually expire conn attempt timeout
|
// Manually expire conn attempt timeout
|
||||||
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
||||||
qEvb_->cancelTimeout(&client->happyEyeballsConnAttemptDelayTimeout());
|
client->happyEyeballsConnAttemptDelayTimeout().cancelTimerCallback();
|
||||||
client->happyEyeballsConnAttemptDelayTimeout().timeoutExpired();
|
client->happyEyeballsConnAttemptDelayTimeout().timeoutExpired();
|
||||||
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(
|
EXPECT_FALSE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
|
|
||||||
// Manually expire loss timeout to trigger write to both first and second
|
// Manually expire loss timeout to trigger write to both first and second
|
||||||
// socket
|
// socket
|
||||||
EXPECT_CALL(*sock, write(firstAddress, _));
|
EXPECT_CALL(*sock, write(firstAddress, _));
|
||||||
EXPECT_CALL(*secondSock, write(secondAddress, _))
|
EXPECT_CALL(*secondSock, write(secondAddress, _))
|
||||||
.WillOnce(SetErrnoAndReturn(EAGAIN, -1));
|
.WillOnce(SetErrnoAndReturn(EAGAIN, -1));
|
||||||
qEvb_->cancelTimeout(&client->lossTimeout());
|
client->lossTimeout().cancelTimerCallback();
|
||||||
client->lossTimeout().timeoutExpired();
|
client->lossTimeout().timeoutExpired();
|
||||||
|
|
||||||
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToFirstSocket);
|
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToFirstSocket);
|
||||||
@@ -1845,7 +1845,7 @@ class QuicClientTransportHappyEyeballsTest
|
|||||||
|
|
||||||
EXPECT_CALL(*sock, write(firstAddress, _)).Times(1);
|
EXPECT_CALL(*sock, write(firstAddress, _)).Times(1);
|
||||||
EXPECT_CALL(*secondSock, write(secondAddress, _)).Times(1);
|
EXPECT_CALL(*secondSock, write(secondAddress, _)).Times(1);
|
||||||
qEvb_->cancelTimeout(&client->lossTimeout());
|
client->lossTimeout().cancelTimerCallback();
|
||||||
client->lossTimeout().timeoutExpired();
|
client->lossTimeout().timeoutExpired();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1859,16 +1859,16 @@ class QuicClientTransportHappyEyeballsTest
|
|||||||
client->start(&clientConnSetupCallback, &clientConnCallback);
|
client->start(&clientConnSetupCallback, &clientConnCallback);
|
||||||
EXPECT_EQ(conn.peerAddress, firstAddress);
|
EXPECT_EQ(conn.peerAddress, firstAddress);
|
||||||
EXPECT_EQ(conn.happyEyeballsState.secondPeerAddress, secondAddress);
|
EXPECT_EQ(conn.happyEyeballsState.secondPeerAddress, secondAddress);
|
||||||
EXPECT_TRUE(qEvb_->isTimeoutScheduled(
|
EXPECT_TRUE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
|
|
||||||
// Manually expire conn attempt timeout
|
// Manually expire conn attempt timeout
|
||||||
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
||||||
qEvb_->cancelTimeout(&client->happyEyeballsConnAttemptDelayTimeout());
|
client->happyEyeballsConnAttemptDelayTimeout().cancelTimerCallback();
|
||||||
client->happyEyeballsConnAttemptDelayTimeout().timeoutExpired();
|
client->happyEyeballsConnAttemptDelayTimeout().timeoutExpired();
|
||||||
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(
|
EXPECT_FALSE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
|
|
||||||
// Manually expire loss timeout to trigger write to both first and second
|
// Manually expire loss timeout to trigger write to both first and second
|
||||||
// socket
|
// socket
|
||||||
@@ -1879,7 +1879,7 @@ class QuicClientTransportHappyEyeballsTest
|
|||||||
// Socket is paused read for the second time when QuicClientTransport dies
|
// Socket is paused read for the second time when QuicClientTransport dies
|
||||||
EXPECT_CALL(*secondSock, pauseRead()).Times(2);
|
EXPECT_CALL(*secondSock, pauseRead()).Times(2);
|
||||||
EXPECT_CALL(*secondSock, close()).Times(1);
|
EXPECT_CALL(*secondSock, close()).Times(1);
|
||||||
qEvb_->cancelTimeout(&client->lossTimeout());
|
client->lossTimeout().cancelTimerCallback();
|
||||||
client->lossTimeout().timeoutExpired();
|
client->lossTimeout().timeoutExpired();
|
||||||
|
|
||||||
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToFirstSocket);
|
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToFirstSocket);
|
||||||
@@ -1887,7 +1887,7 @@ class QuicClientTransportHappyEyeballsTest
|
|||||||
|
|
||||||
EXPECT_CALL(*sock, write(firstAddress, _)).Times(1);
|
EXPECT_CALL(*sock, write(firstAddress, _)).Times(1);
|
||||||
EXPECT_CALL(*secondSock, write(_, _)).Times(0);
|
EXPECT_CALL(*secondSock, write(_, _)).Times(0);
|
||||||
qEvb_->cancelTimeout(&client->lossTimeout());
|
client->lossTimeout().cancelTimerCallback();
|
||||||
client->lossTimeout().timeoutExpired();
|
client->lossTimeout().timeoutExpired();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1902,16 +1902,16 @@ class QuicClientTransportHappyEyeballsTest
|
|||||||
client->start(&clientConnSetupCallback, &clientConnCallback);
|
client->start(&clientConnSetupCallback, &clientConnCallback);
|
||||||
EXPECT_EQ(conn.peerAddress, firstAddress);
|
EXPECT_EQ(conn.peerAddress, firstAddress);
|
||||||
EXPECT_EQ(conn.happyEyeballsState.secondPeerAddress, secondAddress);
|
EXPECT_EQ(conn.happyEyeballsState.secondPeerAddress, secondAddress);
|
||||||
EXPECT_TRUE(qEvb_->isTimeoutScheduled(
|
EXPECT_TRUE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
|
|
||||||
// Manually expire conn attempt timeout
|
// Manually expire conn attempt timeout
|
||||||
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
||||||
qEvb_->cancelTimeout(&client->happyEyeballsConnAttemptDelayTimeout());
|
client->happyEyeballsConnAttemptDelayTimeout().cancelTimerCallback();
|
||||||
client->happyEyeballsConnAttemptDelayTimeout().timeoutExpired();
|
client->happyEyeballsConnAttemptDelayTimeout().timeoutExpired();
|
||||||
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(
|
EXPECT_FALSE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
|
|
||||||
// Manually expire loss timeout to trigger write to both first and second
|
// Manually expire loss timeout to trigger write to both first and second
|
||||||
// socket
|
// socket
|
||||||
@@ -1930,7 +1930,7 @@ class QuicClientTransportHappyEyeballsTest
|
|||||||
// Socket is paused read once during happy eyeballs
|
// Socket is paused read once during happy eyeballs
|
||||||
EXPECT_CALL(*secondSock, pauseRead()).Times(1);
|
EXPECT_CALL(*secondSock, pauseRead()).Times(1);
|
||||||
EXPECT_CALL(*secondSock, close()).Times(1);
|
EXPECT_CALL(*secondSock, close()).Times(1);
|
||||||
qEvb_->cancelTimeout(&client->lossTimeout());
|
client->lossTimeout().cancelTimerCallback();
|
||||||
client->lossTimeout().timeoutExpired();
|
client->lossTimeout().timeoutExpired();
|
||||||
|
|
||||||
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToFirstSocket);
|
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToFirstSocket);
|
||||||
@@ -1938,7 +1938,7 @@ class QuicClientTransportHappyEyeballsTest
|
|||||||
|
|
||||||
EXPECT_CALL(*sock, write(firstAddress, _)).Times(1);
|
EXPECT_CALL(*sock, write(firstAddress, _)).Times(1);
|
||||||
EXPECT_CALL(*secondSock, write(_, _)).Times(0);
|
EXPECT_CALL(*secondSock, write(_, _)).Times(0);
|
||||||
qEvb_->cancelTimeout(&client->lossTimeout());
|
client->lossTimeout().cancelTimerCallback();
|
||||||
client->lossTimeout().timeoutExpired();
|
client->lossTimeout().timeoutExpired();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -1953,16 +1953,16 @@ class QuicClientTransportHappyEyeballsTest
|
|||||||
client->start(&clientConnSetupCallback, &clientConnCallback);
|
client->start(&clientConnSetupCallback, &clientConnCallback);
|
||||||
EXPECT_EQ(conn.peerAddress, firstAddress);
|
EXPECT_EQ(conn.peerAddress, firstAddress);
|
||||||
EXPECT_EQ(conn.happyEyeballsState.secondPeerAddress, secondAddress);
|
EXPECT_EQ(conn.happyEyeballsState.secondPeerAddress, secondAddress);
|
||||||
EXPECT_TRUE(qEvb_->isTimeoutScheduled(
|
EXPECT_TRUE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
|
|
||||||
// Manually expire conn attempt timeout
|
// Manually expire conn attempt timeout
|
||||||
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
||||||
qEvb_->cancelTimeout(&client->happyEyeballsConnAttemptDelayTimeout());
|
client->happyEyeballsConnAttemptDelayTimeout().cancelTimerCallback();
|
||||||
client->happyEyeballsConnAttemptDelayTimeout().timeoutExpired();
|
client->happyEyeballsConnAttemptDelayTimeout().timeoutExpired();
|
||||||
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(
|
EXPECT_FALSE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
|
|
||||||
// Manually expire loss timeout to trigger write to both first and second
|
// Manually expire loss timeout to trigger write to both first and second
|
||||||
// socket
|
// socket
|
||||||
@@ -1970,7 +1970,7 @@ class QuicClientTransportHappyEyeballsTest
|
|||||||
.WillOnce(SetErrnoAndReturn(EAGAIN, -1));
|
.WillOnce(SetErrnoAndReturn(EAGAIN, -1));
|
||||||
EXPECT_CALL(*secondSock, write(secondAddress, _))
|
EXPECT_CALL(*secondSock, write(secondAddress, _))
|
||||||
.WillOnce(SetErrnoAndReturn(EAGAIN, -1));
|
.WillOnce(SetErrnoAndReturn(EAGAIN, -1));
|
||||||
qEvb_->cancelTimeout(&client->lossTimeout());
|
client->lossTimeout().cancelTimerCallback();
|
||||||
client->lossTimeout().timeoutExpired();
|
client->lossTimeout().timeoutExpired();
|
||||||
|
|
||||||
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToFirstSocket);
|
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToFirstSocket);
|
||||||
@@ -1978,7 +1978,7 @@ class QuicClientTransportHappyEyeballsTest
|
|||||||
|
|
||||||
EXPECT_CALL(*sock, write(firstAddress, _)).Times(1);
|
EXPECT_CALL(*sock, write(firstAddress, _)).Times(1);
|
||||||
EXPECT_CALL(*secondSock, write(secondAddress, _)).Times(1);
|
EXPECT_CALL(*secondSock, write(secondAddress, _)).Times(1);
|
||||||
qEvb_->cancelTimeout(&client->lossTimeout());
|
client->lossTimeout().cancelTimerCallback();
|
||||||
client->lossTimeout().timeoutExpired();
|
client->lossTimeout().timeoutExpired();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1992,16 +1992,16 @@ class QuicClientTransportHappyEyeballsTest
|
|||||||
client->start(&clientConnSetupCallback, &clientConnCallback);
|
client->start(&clientConnSetupCallback, &clientConnCallback);
|
||||||
EXPECT_EQ(conn.peerAddress, firstAddress);
|
EXPECT_EQ(conn.peerAddress, firstAddress);
|
||||||
EXPECT_EQ(conn.happyEyeballsState.secondPeerAddress, secondAddress);
|
EXPECT_EQ(conn.happyEyeballsState.secondPeerAddress, secondAddress);
|
||||||
EXPECT_TRUE(qEvb_->isTimeoutScheduled(
|
EXPECT_TRUE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
|
|
||||||
// Manually expire conn attempt timeout
|
// Manually expire conn attempt timeout
|
||||||
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
||||||
qEvb_->cancelTimeout(&client->happyEyeballsConnAttemptDelayTimeout());
|
client->happyEyeballsConnAttemptDelayTimeout().cancelTimerCallback();
|
||||||
client->happyEyeballsConnAttemptDelayTimeout().timeoutExpired();
|
client->happyEyeballsConnAttemptDelayTimeout().timeoutExpired();
|
||||||
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(
|
EXPECT_FALSE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
|
|
||||||
// Manually expire loss timeout to trigger write to both first and second
|
// Manually expire loss timeout to trigger write to both first and second
|
||||||
// socket
|
// socket
|
||||||
@@ -2010,7 +2010,7 @@ class QuicClientTransportHappyEyeballsTest
|
|||||||
EXPECT_CALL(*secondSock, write(secondAddress, _))
|
EXPECT_CALL(*secondSock, write(secondAddress, _))
|
||||||
.WillOnce(SetErrnoAndReturn(EBADF, -1));
|
.WillOnce(SetErrnoAndReturn(EBADF, -1));
|
||||||
EXPECT_CALL(clientConnSetupCallback, onConnectionSetupError(_));
|
EXPECT_CALL(clientConnSetupCallback, onConnectionSetupError(_));
|
||||||
qEvb_->cancelTimeout(&client->lossTimeout());
|
client->lossTimeout().cancelTimerCallback();
|
||||||
client->lossTimeout().timeoutExpired();
|
client->lossTimeout().timeoutExpired();
|
||||||
|
|
||||||
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToFirstSocket);
|
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToFirstSocket);
|
||||||
@@ -2028,16 +2028,16 @@ class QuicClientTransportHappyEyeballsTest
|
|||||||
client->start(&clientConnSetupCallback, &clientConnCallback);
|
client->start(&clientConnSetupCallback, &clientConnCallback);
|
||||||
EXPECT_EQ(conn.peerAddress, firstAddress);
|
EXPECT_EQ(conn.peerAddress, firstAddress);
|
||||||
EXPECT_EQ(conn.happyEyeballsState.secondPeerAddress, secondAddress);
|
EXPECT_EQ(conn.happyEyeballsState.secondPeerAddress, secondAddress);
|
||||||
EXPECT_TRUE(qEvb_->isTimeoutScheduled(
|
EXPECT_TRUE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
|
|
||||||
// Manually expire conn attempt timeout
|
// Manually expire conn attempt timeout
|
||||||
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
||||||
qEvb_->cancelTimeout(&client->happyEyeballsConnAttemptDelayTimeout());
|
client->happyEyeballsConnAttemptDelayTimeout().cancelTimerCallback();
|
||||||
client->happyEyeballsConnAttemptDelayTimeout().timeoutExpired();
|
client->happyEyeballsConnAttemptDelayTimeout().timeoutExpired();
|
||||||
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(
|
EXPECT_FALSE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
|
|
||||||
union {
|
union {
|
||||||
struct cmsghdr hdr;
|
struct cmsghdr hdr;
|
||||||
@@ -3350,11 +3350,11 @@ TEST_F(QuicClientTransportAfterStartTest, IdleTimerResetOnRecvNewData) {
|
|||||||
0 /* cipherOverhead */,
|
0 /* cipherOverhead */,
|
||||||
0 /* largestAcked */));
|
0 /* largestAcked */));
|
||||||
|
|
||||||
qEvb_->cancelTimeout(&client->idleTimeout());
|
client->idleTimeout().cancelTimerCallback();
|
||||||
ASSERT_FALSE(qEvb_->isTimeoutScheduled(&client->idleTimeout()));
|
ASSERT_FALSE(client->idleTimeout().isTimerCallbackScheduled());
|
||||||
deliverData(packet->coalesce());
|
deliverData(packet->coalesce());
|
||||||
ASSERT_TRUE(client->getConn().receivedNewPacketBeforeWrite);
|
ASSERT_TRUE(client->getConn().receivedNewPacketBeforeWrite);
|
||||||
ASSERT_TRUE(qEvb_->isTimeoutScheduled(&client->idleTimeout()));
|
ASSERT_TRUE(client->idleTimeout().isTimerCallbackScheduled());
|
||||||
|
|
||||||
auto packet2 = packetToBuf(createStreamPacket(
|
auto packet2 = packetToBuf(createStreamPacket(
|
||||||
*serverChosenConnId /* src */,
|
*serverChosenConnId /* src */,
|
||||||
@@ -3364,11 +3364,11 @@ TEST_F(QuicClientTransportAfterStartTest, IdleTimerResetOnRecvNewData) {
|
|||||||
*expected,
|
*expected,
|
||||||
0 /* cipherOverhead */,
|
0 /* cipherOverhead */,
|
||||||
0 /* largestAcked */));
|
0 /* largestAcked */));
|
||||||
qEvb_->cancelTimeout(&client->idleTimeout());
|
client->idleTimeout().cancelTimerCallback();
|
||||||
ASSERT_FALSE(qEvb_->isTimeoutScheduled(&client->idleTimeout()));
|
ASSERT_FALSE(client->idleTimeout().isTimerCallbackScheduled());
|
||||||
deliverData(packet2->coalesce());
|
deliverData(packet2->coalesce());
|
||||||
ASSERT_TRUE(client->getConn().receivedNewPacketBeforeWrite);
|
ASSERT_TRUE(client->getConn().receivedNewPacketBeforeWrite);
|
||||||
ASSERT_TRUE(qEvb_->isTimeoutScheduled(&client->idleTimeout()));
|
ASSERT_TRUE(client->idleTimeout().isTimerCallbackScheduled());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(QuicClientTransportAfterStartTest, IdleTimerNotResetOnDuplicatePacket) {
|
TEST_F(QuicClientTransportAfterStartTest, IdleTimerNotResetOnDuplicatePacket) {
|
||||||
@@ -3388,11 +3388,11 @@ TEST_F(QuicClientTransportAfterStartTest, IdleTimerNotResetOnDuplicatePacket) {
|
|||||||
deliverData(packet->coalesce(), false);
|
deliverData(packet->coalesce(), false);
|
||||||
|
|
||||||
ASSERT_TRUE(client->getConn().receivedNewPacketBeforeWrite);
|
ASSERT_TRUE(client->getConn().receivedNewPacketBeforeWrite);
|
||||||
ASSERT_TRUE(qEvb_->isTimeoutScheduled(&client->idleTimeout()));
|
ASSERT_TRUE(client->idleTimeout().isTimerCallbackScheduled());
|
||||||
|
|
||||||
qEvb_->cancelTimeout(&client->idleTimeout());
|
client->idleTimeout().cancelTimerCallback();
|
||||||
client->getNonConstConn().receivedNewPacketBeforeWrite = false;
|
client->getNonConstConn().receivedNewPacketBeforeWrite = false;
|
||||||
ASSERT_FALSE(qEvb_->isTimeoutScheduled(&client->idleTimeout()));
|
ASSERT_FALSE(client->idleTimeout().isTimerCallbackScheduled());
|
||||||
quicStats_ = std::make_shared<testing::NiceMock<MockQuicStats>>();
|
quicStats_ = std::make_shared<testing::NiceMock<MockQuicStats>>();
|
||||||
client->setTransportStatsCallback(quicStats_);
|
client->setTransportStatsCallback(quicStats_);
|
||||||
EXPECT_CALL(*quicStats_, onDuplicatedPacketReceived());
|
EXPECT_CALL(*quicStats_, onDuplicatedPacketReceived());
|
||||||
@@ -3400,7 +3400,7 @@ TEST_F(QuicClientTransportAfterStartTest, IdleTimerNotResetOnDuplicatePacket) {
|
|||||||
deliverData(packet->coalesce(), false);
|
deliverData(packet->coalesce(), false);
|
||||||
|
|
||||||
ASSERT_FALSE(client->getConn().receivedNewPacketBeforeWrite);
|
ASSERT_FALSE(client->getConn().receivedNewPacketBeforeWrite);
|
||||||
ASSERT_FALSE(qEvb_->isTimeoutScheduled(&client->idleTimeout()));
|
ASSERT_FALSE(client->idleTimeout().isTimerCallbackScheduled());
|
||||||
client->closeNow(folly::none);
|
client->closeNow(folly::none);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3427,14 +3427,14 @@ TEST_P(QuicClientTransportAfterStartTestClose, TimeoutsNotSetAfterClose) {
|
|||||||
} else {
|
} else {
|
||||||
client->close(folly::none);
|
client->close(folly::none);
|
||||||
}
|
}
|
||||||
qEvb_->cancelTimeout(&client->idleTimeout());
|
client->idleTimeout().cancelTimerCallback();
|
||||||
ASSERT_FALSE(qEvb_->isTimeoutScheduled(&client->idleTimeout()));
|
ASSERT_FALSE(client->idleTimeout().isTimerCallbackScheduled());
|
||||||
|
|
||||||
deliverDataWithoutErrorCheck(packet->coalesce());
|
deliverDataWithoutErrorCheck(packet->coalesce());
|
||||||
ASSERT_FALSE(qEvb_->isTimeoutScheduled(&client->idleTimeout()));
|
ASSERT_FALSE(client->idleTimeout().isTimerCallbackScheduled());
|
||||||
ASSERT_FALSE(qEvb_->isTimeoutScheduled(&client->lossTimeout()));
|
ASSERT_FALSE(client->lossTimeout().isTimerCallbackScheduled());
|
||||||
ASSERT_FALSE(qEvb_->isTimeoutScheduled(&client->ackTimeout()));
|
ASSERT_FALSE(client->ackTimeout().isTimerCallbackScheduled());
|
||||||
ASSERT_TRUE(qEvb_->isTimeoutScheduled(&client->drainTimeout()));
|
ASSERT_TRUE(client->drainTimeout().isTimerCallbackScheduled());
|
||||||
|
|
||||||
std::vector<int> indices =
|
std::vector<int> indices =
|
||||||
getQLogEventIndices(QLogEventType::PacketDrop, qLogger);
|
getQLogEventIndices(QLogEventType::PacketDrop, qLogger);
|
||||||
@@ -3450,13 +3450,13 @@ TEST_F(QuicClientTransportAfterStartTest, IdleTimerNotResetOnWritingOldData) {
|
|||||||
|
|
||||||
// There should still be outstanding packets
|
// There should still be outstanding packets
|
||||||
auto expected = IOBuf::copyBuffer("hello");
|
auto expected = IOBuf::copyBuffer("hello");
|
||||||
qEvb_->cancelTimeout(&client->idleTimeout());
|
client->idleTimeout().cancelTimerCallback();
|
||||||
ASSERT_FALSE(qEvb_->isTimeoutScheduled(&client->idleTimeout()));
|
ASSERT_FALSE(client->idleTimeout().isTimerCallbackScheduled());
|
||||||
client->writeChain(streamId, expected->clone(), false);
|
client->writeChain(streamId, expected->clone(), false);
|
||||||
loopForWrites();
|
loopForWrites();
|
||||||
|
|
||||||
ASSERT_FALSE(client->getConn().receivedNewPacketBeforeWrite);
|
ASSERT_FALSE(client->getConn().receivedNewPacketBeforeWrite);
|
||||||
ASSERT_FALSE(qEvb_->isTimeoutScheduled(&client->idleTimeout()));
|
ASSERT_FALSE(client->idleTimeout().isTimerCallbackScheduled());
|
||||||
client->closeNow(folly::none);
|
client->closeNow(folly::none);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3477,12 +3477,12 @@ TEST_F(QuicClientTransportAfterStartTest, IdleTimerResetNoOutstandingPackets) {
|
|||||||
// Clear out all the outstanding packets to simulate quiescent state.
|
// Clear out all the outstanding packets to simulate quiescent state.
|
||||||
client->getNonConstConn().receivedNewPacketBeforeWrite = false;
|
client->getNonConstConn().receivedNewPacketBeforeWrite = false;
|
||||||
client->getNonConstConn().outstandings.reset();
|
client->getNonConstConn().outstandings.reset();
|
||||||
qEvb_->cancelTimeout(&client->idleTimeout());
|
client->idleTimeout().cancelTimerCallback();
|
||||||
auto streamId = client->createBidirectionalStream().value();
|
auto streamId = client->createBidirectionalStream().value();
|
||||||
auto expected = folly::IOBuf::copyBuffer("hello");
|
auto expected = folly::IOBuf::copyBuffer("hello");
|
||||||
client->writeChain(streamId, expected->clone(), false);
|
client->writeChain(streamId, expected->clone(), false);
|
||||||
loopForWrites();
|
loopForWrites();
|
||||||
ASSERT_TRUE(qEvb_->isTimeoutScheduled(&client->idleTimeout()));
|
ASSERT_TRUE(client->idleTimeout().isTimerCallbackScheduled());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(QuicClientTransportAfterStartTest, IdleTimeoutExpired) {
|
TEST_F(QuicClientTransportAfterStartTest, IdleTimeoutExpired) {
|
||||||
@@ -3490,7 +3490,7 @@ TEST_F(QuicClientTransportAfterStartTest, IdleTimeoutExpired) {
|
|||||||
socketWrites.clear();
|
socketWrites.clear();
|
||||||
client->idleTimeout().timeoutExpired();
|
client->idleTimeout().timeoutExpired();
|
||||||
|
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(&client->idleTimeout()));
|
EXPECT_FALSE(client->idleTimeout().isTimerCallbackScheduled());
|
||||||
EXPECT_TRUE(client->isDraining());
|
EXPECT_TRUE(client->isDraining());
|
||||||
EXPECT_TRUE(client->isClosed());
|
EXPECT_TRUE(client->isClosed());
|
||||||
|
|
||||||
@@ -4633,7 +4633,7 @@ TEST_F(QuicClientTransportAfterStartTest, WriteThrowsExceptionWhileDraining) {
|
|||||||
toString(LocalErrorCode::INTERNAL_ERROR).str());
|
toString(LocalErrorCode::INTERNAL_ERROR).str());
|
||||||
EXPECT_CALL(*sock, write(_, _)).WillRepeatedly(SetErrnoAndReturn(EBADF, -1));
|
EXPECT_CALL(*sock, write(_, _)).WillRepeatedly(SetErrnoAndReturn(EBADF, -1));
|
||||||
client->close(err);
|
client->close(err);
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(&client->idleTimeout()));
|
EXPECT_FALSE(client->idleTimeout().isTimerCallbackScheduled());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(QuicClientTransportAfterStartTest, DestroyEvbWhileLossTimeoutActive) {
|
TEST_F(QuicClientTransportAfterStartTest, DestroyEvbWhileLossTimeoutActive) {
|
||||||
@@ -4644,7 +4644,7 @@ TEST_F(QuicClientTransportAfterStartTest, DestroyEvbWhileLossTimeoutActive) {
|
|||||||
auto write = IOBuf::copyBuffer("no");
|
auto write = IOBuf::copyBuffer("no");
|
||||||
client->writeChain(streamId, write->clone(), true);
|
client->writeChain(streamId, write->clone(), true);
|
||||||
loopForWrites();
|
loopForWrites();
|
||||||
EXPECT_TRUE(qEvb_->isTimeoutScheduled(&client->lossTimeout()));
|
EXPECT_TRUE(client->lossTimeout().isTimerCallbackScheduled());
|
||||||
eventbase_.reset();
|
eventbase_.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5383,10 +5383,10 @@ TEST_F(
|
|||||||
auto& conn = client->getConn();
|
auto& conn = client->getConn();
|
||||||
EXPECT_EQ(conn.peerAddress, firstAddress);
|
EXPECT_EQ(conn.peerAddress, firstAddress);
|
||||||
EXPECT_EQ(conn.happyEyeballsState.secondPeerAddress, secondAddress);
|
EXPECT_EQ(conn.happyEyeballsState.secondPeerAddress, secondAddress);
|
||||||
EXPECT_TRUE(qEvb_->isTimeoutScheduled(
|
EXPECT_TRUE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
// Cancel the delay timer because we want to manually fire it
|
// Cancel the delay timer because we want to manually fire it
|
||||||
qEvb_->cancelTimeout(&client->happyEyeballsConnAttemptDelayTimeout());
|
client->happyEyeballsConnAttemptDelayTimeout().cancelTimerCallback();
|
||||||
|
|
||||||
auto streamId = client->createBidirectionalStream().value();
|
auto streamId = client->createBidirectionalStream().value();
|
||||||
client->writeChain(streamId, IOBuf::copyBuffer("hello"), true);
|
client->writeChain(streamId, IOBuf::copyBuffer("hello"), true);
|
||||||
@@ -5399,8 +5399,8 @@ TEST_F(
|
|||||||
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
EXPECT_FALSE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
||||||
client->happyEyeballsConnAttemptDelayTimeout().timeoutExpired();
|
client->happyEyeballsConnAttemptDelayTimeout().timeoutExpired();
|
||||||
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
EXPECT_TRUE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(
|
EXPECT_FALSE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
loopForWrites();
|
loopForWrites();
|
||||||
// Declared lost
|
// Declared lost
|
||||||
EXPECT_FALSE(zeroRttPacketsOutstanding());
|
EXPECT_FALSE(zeroRttPacketsOutstanding());
|
||||||
@@ -5422,7 +5422,7 @@ TEST_F(
|
|||||||
socketWrites.push_back(buf->clone());
|
socketWrites.push_back(buf->clone());
|
||||||
return buf->computeChainDataLength();
|
return buf->computeChainDataLength();
|
||||||
}));
|
}));
|
||||||
qEvb_->cancelTimeout(&client->lossTimeout());
|
client->lossTimeout().cancelTimerCallback();
|
||||||
client->lossTimeout().timeoutExpired();
|
client->lossTimeout().timeoutExpired();
|
||||||
ASSERT_EQ(socketWrites.size(), 4);
|
ASSERT_EQ(socketWrites.size(), 4);
|
||||||
EXPECT_TRUE(
|
EXPECT_TRUE(
|
||||||
@@ -5473,8 +5473,8 @@ TEST_F(
|
|||||||
auto& conn = client->getConn();
|
auto& conn = client->getConn();
|
||||||
EXPECT_EQ(conn.peerAddress, firstAddress);
|
EXPECT_EQ(conn.peerAddress, firstAddress);
|
||||||
EXPECT_EQ(conn.happyEyeballsState.secondPeerAddress, secondAddress);
|
EXPECT_EQ(conn.happyEyeballsState.secondPeerAddress, secondAddress);
|
||||||
ASSERT_TRUE(qEvb_->isTimeoutScheduled(
|
ASSERT_TRUE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
|
|
||||||
EXPECT_CALL(*sock, write(firstAddress, _))
|
EXPECT_CALL(*sock, write(firstAddress, _))
|
||||||
.WillOnce(Invoke(
|
.WillOnce(Invoke(
|
||||||
@@ -5486,12 +5486,12 @@ TEST_F(
|
|||||||
client->writeChain(streamId, IOBuf::copyBuffer("hello"), true);
|
client->writeChain(streamId, IOBuf::copyBuffer("hello"), true);
|
||||||
loopForWrites();
|
loopForWrites();
|
||||||
EXPECT_FALSE(zeroRttPacketsOutstanding());
|
EXPECT_FALSE(zeroRttPacketsOutstanding());
|
||||||
ASSERT_FALSE(qEvb_->isTimeoutScheduled(
|
ASSERT_FALSE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
|
|
||||||
ASSERT_TRUE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
ASSERT_TRUE(conn.happyEyeballsState.shouldWriteToSecondSocket);
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(
|
EXPECT_FALSE(client->happyEyeballsConnAttemptDelayTimeout()
|
||||||
&client->happyEyeballsConnAttemptDelayTimeout()));
|
.isTimerCallbackScheduled());
|
||||||
|
|
||||||
EXPECT_CALL(*secondSock, write(secondAddress, _))
|
EXPECT_CALL(*secondSock, write(secondAddress, _))
|
||||||
.Times(2)
|
.Times(2)
|
||||||
@@ -5500,7 +5500,7 @@ TEST_F(
|
|||||||
socketWrites.push_back(buf->clone());
|
socketWrites.push_back(buf->clone());
|
||||||
return buf->computeChainDataLength();
|
return buf->computeChainDataLength();
|
||||||
}));
|
}));
|
||||||
qEvb_->cancelTimeout(&client->lossTimeout());
|
client->lossTimeout().cancelTimerCallback();
|
||||||
client->lossTimeout().timeoutExpired();
|
client->lossTimeout().timeoutExpired();
|
||||||
ASSERT_EQ(socketWrites.size(), 2);
|
ASSERT_EQ(socketWrites.size(), 2);
|
||||||
EXPECT_TRUE(
|
EXPECT_TRUE(
|
||||||
|
@@ -115,7 +115,7 @@ class TestingQuicClientTransport : public QuicClientTransport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool isDraining() {
|
bool isDraining() {
|
||||||
return evb_->isTimeoutScheduled(&drainTimeout_);
|
return drainTimeout_.isTimerCallbackScheduled();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& serverInitialParamsSet() {
|
auto& serverInitialParamsSet() {
|
||||||
@@ -549,7 +549,7 @@ class QuicClientTransportTestBase : public virtual testing::Test {
|
|||||||
setUpSocketExpectations();
|
setUpSocketExpectations();
|
||||||
client->start(&clientConnSetupCallback, &clientConnCallback);
|
client->start(&clientConnSetupCallback, &clientConnCallback);
|
||||||
setConnectionIds();
|
setConnectionIds();
|
||||||
EXPECT_TRUE(qEvb_->isTimeoutScheduled(&client->idleTimeout()));
|
EXPECT_TRUE(client->idleTimeout().isTimerCallbackScheduled());
|
||||||
|
|
||||||
EXPECT_EQ(socketWrites.size(), 1);
|
EXPECT_EQ(socketWrites.size(), 1);
|
||||||
EXPECT_TRUE(
|
EXPECT_TRUE(
|
||||||
|
@@ -104,7 +104,7 @@ void startHappyEyeballs(
|
|||||||
options);
|
options);
|
||||||
} catch (const std::exception&) {
|
} catch (const std::exception&) {
|
||||||
// If second socket bind throws exception, give it up
|
// If second socket bind throws exception, give it up
|
||||||
evb->cancelTimeout(&connAttemptDelayTimeout);
|
connAttemptDelayTimeout.cancelTimerCallback();
|
||||||
connection.happyEyeballsState.finished = true;
|
connection.happyEyeballsState.finished = true;
|
||||||
}
|
}
|
||||||
} else if (connection.happyEyeballsState.v6PeerAddress.isInitialized()) {
|
} else if (connection.happyEyeballsState.v6PeerAddress.isInitialized()) {
|
||||||
@@ -192,7 +192,7 @@ void happyEyeballsOnDataReceived(
|
|||||||
if (connection.happyEyeballsState.finished) {
|
if (connection.happyEyeballsState.finished) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
socket->getEventBase()->cancelTimeout(&connAttemptDelayTimeout);
|
connAttemptDelayTimeout.cancelTimerCallback();
|
||||||
connection.happyEyeballsState.finished = true;
|
connection.happyEyeballsState.finished = true;
|
||||||
connection.happyEyeballsState.shouldWriteToFirstSocket = true;
|
connection.happyEyeballsState.shouldWriteToFirstSocket = true;
|
||||||
connection.happyEyeballsState.shouldWriteToSecondSocket = false;
|
connection.happyEyeballsState.shouldWriteToSecondSocket = false;
|
||||||
|
@@ -182,11 +182,11 @@ TEST_F(QuicServerTransportTest, IdleTimerResetOnRecvNewData) {
|
|||||||
0 /* cipherOverhead */,
|
0 /* cipherOverhead */,
|
||||||
0 /* largestAcked */));
|
0 /* largestAcked */));
|
||||||
|
|
||||||
qEvb_->cancelTimeout(&server->idleTimeout());
|
server->idleTimeout().cancelTimerCallback();
|
||||||
ASSERT_FALSE(qEvb_->isTimeoutScheduled(&server->idleTimeout()));
|
ASSERT_FALSE(server->idleTimeout().isTimerCallbackScheduled());
|
||||||
recvEncryptedStream(streamId, *expected);
|
recvEncryptedStream(streamId, *expected);
|
||||||
ASSERT_TRUE(qEvb_->isTimeoutScheduled(&server->idleTimeout()));
|
ASSERT_TRUE(server->idleTimeout().isTimerCallbackScheduled());
|
||||||
ASSERT_TRUE(qEvb_->isTimeoutScheduled(&server->keepaliveTimeout()));
|
ASSERT_TRUE(server->keepaliveTimeout().isTimerCallbackScheduled());
|
||||||
EXPECT_CALL(*quicStats_, onQuicStreamClosed());
|
EXPECT_CALL(*quicStats_, onQuicStreamClosed());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,17 +196,17 @@ TEST_F(QuicServerTransportTest, IdleTimerNotResetOnDuplicatePacket) {
|
|||||||
|
|
||||||
auto expected = IOBuf::copyBuffer("hello");
|
auto expected = IOBuf::copyBuffer("hello");
|
||||||
auto packet = recvEncryptedStream(streamId, *expected);
|
auto packet = recvEncryptedStream(streamId, *expected);
|
||||||
ASSERT_TRUE(qEvb_->isTimeoutScheduled(&server->idleTimeout()));
|
ASSERT_TRUE(server->idleTimeout().isTimerCallbackScheduled());
|
||||||
ASSERT_TRUE(qEvb_->isTimeoutScheduled(&server->keepaliveTimeout()));
|
ASSERT_TRUE(server->keepaliveTimeout().isTimerCallbackScheduled());
|
||||||
|
|
||||||
qEvb_->cancelTimeout(&server->idleTimeout());
|
server->idleTimeout().cancelTimerCallback();
|
||||||
qEvb_->cancelTimeout(&server->keepaliveTimeout());
|
server->keepaliveTimeout().cancelTimerCallback();
|
||||||
ASSERT_FALSE(qEvb_->isTimeoutScheduled(&server->idleTimeout()));
|
ASSERT_FALSE(server->idleTimeout().isTimerCallbackScheduled());
|
||||||
ASSERT_FALSE(qEvb_->isTimeoutScheduled(&server->keepaliveTimeout()));
|
ASSERT_FALSE(server->keepaliveTimeout().isTimerCallbackScheduled());
|
||||||
// Try delivering the same packet again
|
// Try delivering the same packet again
|
||||||
deliverData(packet->clone(), false);
|
deliverData(packet->clone(), false);
|
||||||
ASSERT_FALSE(qEvb_->isTimeoutScheduled(&server->idleTimeout()));
|
ASSERT_FALSE(server->idleTimeout().isTimerCallbackScheduled());
|
||||||
ASSERT_FALSE(qEvb_->isTimeoutScheduled(&server->keepaliveTimeout()));
|
ASSERT_FALSE(server->keepaliveTimeout().isTimerCallbackScheduled());
|
||||||
EXPECT_CALL(*quicStats_, onQuicStreamClosed());
|
EXPECT_CALL(*quicStats_, onQuicStreamClosed());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,29 +217,29 @@ TEST_F(QuicServerTransportTest, IdleTimerNotResetWhenDataOutstanding) {
|
|||||||
server->getNonConstConn().receivedNewPacketBeforeWrite = false;
|
server->getNonConstConn().receivedNewPacketBeforeWrite = false;
|
||||||
StreamId streamId = server->createBidirectionalStream().value();
|
StreamId streamId = server->createBidirectionalStream().value();
|
||||||
|
|
||||||
qEvb_->cancelTimeout(&server->idleTimeout());
|
server->idleTimeout().cancelTimerCallback();
|
||||||
qEvb_->cancelTimeout(&server->keepaliveTimeout());
|
server->keepaliveTimeout().cancelTimerCallback();
|
||||||
ASSERT_FALSE(qEvb_->isTimeoutScheduled(&server->idleTimeout()));
|
ASSERT_FALSE(server->idleTimeout().isTimerCallbackScheduled());
|
||||||
server->writeChain(
|
server->writeChain(
|
||||||
streamId,
|
streamId,
|
||||||
IOBuf::copyBuffer("And if the darkness is to keep us apart"),
|
IOBuf::copyBuffer("And if the darkness is to keep us apart"),
|
||||||
false);
|
false);
|
||||||
loopForWrites();
|
loopForWrites();
|
||||||
// It was the first packet
|
// It was the first packet
|
||||||
EXPECT_TRUE(qEvb_->isTimeoutScheduled(&server->idleTimeout()));
|
EXPECT_TRUE(server->idleTimeout().isTimerCallbackScheduled());
|
||||||
EXPECT_TRUE(qEvb_->isTimeoutScheduled(&server->keepaliveTimeout()));
|
EXPECT_TRUE(server->keepaliveTimeout().isTimerCallbackScheduled());
|
||||||
|
|
||||||
// cancel it and write something else. This time idle timer shouldn't set.
|
// cancel it and write something else. This time idle timer shouldn't set.
|
||||||
qEvb_->cancelTimeout(&server->idleTimeout());
|
server->idleTimeout().cancelTimerCallback();
|
||||||
qEvb_->cancelTimeout(&server->keepaliveTimeout());
|
server->keepaliveTimeout().cancelTimerCallback();
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(&server->idleTimeout()));
|
EXPECT_FALSE(server->idleTimeout().isTimerCallbackScheduled());
|
||||||
server->writeChain(
|
server->writeChain(
|
||||||
streamId,
|
streamId,
|
||||||
IOBuf::copyBuffer("And if the daylight feels like it's a long way off"),
|
IOBuf::copyBuffer("And if the daylight feels like it's a long way off"),
|
||||||
false);
|
false);
|
||||||
loopForWrites();
|
loopForWrites();
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(&server->idleTimeout()));
|
EXPECT_FALSE(server->idleTimeout().isTimerCallbackScheduled());
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(&server->keepaliveTimeout()));
|
EXPECT_FALSE(server->keepaliveTimeout().isTimerCallbackScheduled());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(QuicServerTransportTest, TimeoutsNotSetAfterClose) {
|
TEST_F(QuicServerTransportTest, TimeoutsNotSetAfterClose) {
|
||||||
@@ -257,16 +257,16 @@ TEST_F(QuicServerTransportTest, TimeoutsNotSetAfterClose) {
|
|||||||
server->close(QuicError(
|
server->close(QuicError(
|
||||||
QuicErrorCode(TransportErrorCode::INTERNAL_ERROR),
|
QuicErrorCode(TransportErrorCode::INTERNAL_ERROR),
|
||||||
std::string("how about no")));
|
std::string("how about no")));
|
||||||
qEvb_->cancelTimeout(&server->idleTimeout());
|
server->idleTimeout().cancelTimerCallback();
|
||||||
qEvb_->cancelTimeout(&server->keepaliveTimeout());
|
server->keepaliveTimeout().cancelTimerCallback();
|
||||||
ASSERT_FALSE(qEvb_->isTimeoutScheduled(&server->idleTimeout()));
|
ASSERT_FALSE(server->idleTimeout().isTimerCallbackScheduled());
|
||||||
|
|
||||||
deliverDataWithoutErrorCheck(packet->clone());
|
deliverDataWithoutErrorCheck(packet->clone());
|
||||||
ASSERT_FALSE(qEvb_->isTimeoutScheduled(&server->idleTimeout()));
|
ASSERT_FALSE(server->idleTimeout().isTimerCallbackScheduled());
|
||||||
ASSERT_FALSE(qEvb_->isTimeoutScheduled(&server->keepaliveTimeout()));
|
ASSERT_FALSE(server->keepaliveTimeout().isTimerCallbackScheduled());
|
||||||
ASSERT_FALSE(qEvb_->isTimeoutScheduled(&server->lossTimeout()));
|
ASSERT_FALSE(server->lossTimeout().isTimerCallbackScheduled());
|
||||||
ASSERT_FALSE(qEvb_->isTimeoutScheduled(&server->ackTimeout()));
|
ASSERT_FALSE(server->ackTimeout().isTimerCallbackScheduled());
|
||||||
ASSERT_TRUE(qEvb_->isTimeoutScheduled(&server->drainTimeout()));
|
ASSERT_TRUE(server->drainTimeout().isTimerCallbackScheduled());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(QuicServerTransportTest, InvalidMigrationNoDrain) {
|
TEST_F(QuicServerTransportTest, InvalidMigrationNoDrain) {
|
||||||
@@ -284,22 +284,22 @@ TEST_F(QuicServerTransportTest, InvalidMigrationNoDrain) {
|
|||||||
server->close(QuicError(
|
server->close(QuicError(
|
||||||
QuicErrorCode(TransportErrorCode::INVALID_MIGRATION),
|
QuicErrorCode(TransportErrorCode::INVALID_MIGRATION),
|
||||||
std::string("migration disabled")));
|
std::string("migration disabled")));
|
||||||
qEvb_->cancelTimeout(&server->idleTimeout());
|
server->idleTimeout().cancelTimerCallback();
|
||||||
qEvb_->cancelTimeout(&server->keepaliveTimeout());
|
server->keepaliveTimeout().cancelTimerCallback();
|
||||||
ASSERT_FALSE(qEvb_->isTimeoutScheduled(&server->idleTimeout()));
|
ASSERT_FALSE(server->idleTimeout().isTimerCallbackScheduled());
|
||||||
|
|
||||||
deliverDataWithoutErrorCheck(packet->clone());
|
deliverDataWithoutErrorCheck(packet->clone());
|
||||||
ASSERT_FALSE(qEvb_->isTimeoutScheduled(&server->idleTimeout()));
|
ASSERT_FALSE(server->idleTimeout().isTimerCallbackScheduled());
|
||||||
ASSERT_FALSE(qEvb_->isTimeoutScheduled(&server->keepaliveTimeout()));
|
ASSERT_FALSE(server->keepaliveTimeout().isTimerCallbackScheduled());
|
||||||
ASSERT_FALSE(qEvb_->isTimeoutScheduled(&server->lossTimeout()));
|
ASSERT_FALSE(server->lossTimeout().isTimerCallbackScheduled());
|
||||||
ASSERT_FALSE(qEvb_->isTimeoutScheduled(&server->ackTimeout()));
|
ASSERT_FALSE(server->ackTimeout().isTimerCallbackScheduled());
|
||||||
ASSERT_FALSE(qEvb_->isTimeoutScheduled(&server->drainTimeout()));
|
ASSERT_FALSE(server->drainTimeout().isTimerCallbackScheduled());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(QuicServerTransportTest, IdleTimeoutExpired) {
|
TEST_F(QuicServerTransportTest, IdleTimeoutExpired) {
|
||||||
server->idleTimeout().timeoutExpired();
|
server->idleTimeout().timeoutExpired();
|
||||||
|
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(&server->idleTimeout()));
|
EXPECT_FALSE(server->idleTimeout().isTimerCallbackScheduled());
|
||||||
EXPECT_TRUE(server->isDraining());
|
EXPECT_TRUE(server->isDraining());
|
||||||
EXPECT_TRUE(server->isClosed());
|
EXPECT_TRUE(server->isClosed());
|
||||||
auto serverReadCodec = makeClientEncryptedCodec();
|
auto serverReadCodec = makeClientEncryptedCodec();
|
||||||
@@ -314,14 +314,14 @@ TEST_F(QuicServerTransportTest, KeepaliveTimeoutExpired) {
|
|||||||
|
|
||||||
EXPECT_FALSE(server->isDraining());
|
EXPECT_FALSE(server->isDraining());
|
||||||
EXPECT_FALSE(server->isClosed());
|
EXPECT_FALSE(server->isClosed());
|
||||||
qEvb_->cancelTimeout(&server->idleTimeout());
|
server->idleTimeout().cancelTimerCallback();
|
||||||
qEvb_->cancelTimeout(&server->keepaliveTimeout());
|
server->keepaliveTimeout().cancelTimerCallback();
|
||||||
server->getNonConstConn().receivedNewPacketBeforeWrite = true;
|
server->getNonConstConn().receivedNewPacketBeforeWrite = true;
|
||||||
// After we write, the idletimout and keepalive timeout should be
|
// After we write, the idletimout and keepalive timeout should be
|
||||||
// scheduled and there should be a ping written.
|
// scheduled and there should be a ping written.
|
||||||
loopForWrites();
|
loopForWrites();
|
||||||
EXPECT_TRUE(qEvb_->isTimeoutScheduled(&server->idleTimeout()));
|
EXPECT_TRUE(server->idleTimeout().isTimerCallbackScheduled());
|
||||||
EXPECT_TRUE(qEvb_->isTimeoutScheduled(&server->keepaliveTimeout()));
|
EXPECT_TRUE(server->keepaliveTimeout().isTimerCallbackScheduled());
|
||||||
auto serverReadCodec = makeClientEncryptedCodec();
|
auto serverReadCodec = makeClientEncryptedCodec();
|
||||||
EXPECT_TRUE(verifyFramePresent(
|
EXPECT_TRUE(verifyFramePresent(
|
||||||
serverWrites, *serverReadCodec, QuicFrame::Type::PingFrame));
|
serverWrites, *serverReadCodec, QuicFrame::Type::PingFrame));
|
||||||
@@ -330,8 +330,8 @@ TEST_F(QuicServerTransportTest, KeepaliveTimeoutExpired) {
|
|||||||
TEST_F(QuicServerTransportTest, RecvDataAfterIdleTimeout) {
|
TEST_F(QuicServerTransportTest, RecvDataAfterIdleTimeout) {
|
||||||
server->idleTimeout().timeoutExpired();
|
server->idleTimeout().timeoutExpired();
|
||||||
|
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(&server->idleTimeout()));
|
EXPECT_FALSE(server->idleTimeout().isTimerCallbackScheduled());
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(&server->keepaliveTimeout()));
|
EXPECT_FALSE(server->keepaliveTimeout().isTimerCallbackScheduled());
|
||||||
EXPECT_TRUE(server->isDraining());
|
EXPECT_TRUE(server->isDraining());
|
||||||
EXPECT_TRUE(server->isClosed());
|
EXPECT_TRUE(server->isClosed());
|
||||||
|
|
||||||
@@ -1745,8 +1745,8 @@ TEST_F(QuicServerTransportTest, ShortHeaderPacketWithNoFramesAfterClose) {
|
|||||||
server->close(QuicError(
|
server->close(QuicError(
|
||||||
QuicErrorCode(TransportErrorCode::INTERNAL_ERROR),
|
QuicErrorCode(TransportErrorCode::INTERNAL_ERROR),
|
||||||
std::string("test close")));
|
std::string("test close")));
|
||||||
qEvb_->cancelTimeout(&server->idleTimeout());
|
server->idleTimeout().cancelTimerCallback();
|
||||||
ASSERT_FALSE(qEvb_->isTimeoutScheduled(&server->idleTimeout()));
|
ASSERT_FALSE(server->idleTimeout().isTimerCallbackScheduled());
|
||||||
|
|
||||||
ShortHeader header(
|
ShortHeader header(
|
||||||
ProtectionType::KeyPhaseZero,
|
ProtectionType::KeyPhaseZero,
|
||||||
@@ -1940,7 +1940,7 @@ TEST_P(QuicServerTransportAllowMigrationTest, MigrateToUnvalidatedPeer) {
|
|||||||
EXPECT_FALSE(server->getConn().pendingEvents.pathChallenge);
|
EXPECT_FALSE(server->getConn().pendingEvents.pathChallenge);
|
||||||
EXPECT_TRUE(server->getConn().outstandingPathValidation);
|
EXPECT_TRUE(server->getConn().outstandingPathValidation);
|
||||||
EXPECT_TRUE(server->getConn().pendingEvents.schedulePathValidationTimeout);
|
EXPECT_TRUE(server->getConn().pendingEvents.schedulePathValidationTimeout);
|
||||||
EXPECT_TRUE(qEvb_->isTimeoutScheduled(&server->pathValidationTimeout()));
|
EXPECT_TRUE(server->pathValidationTimeout().isTimerCallbackScheduled());
|
||||||
|
|
||||||
EXPECT_TRUE(server->getConn().pathValidationLimiter != nullptr);
|
EXPECT_TRUE(server->getConn().pathValidationLimiter != nullptr);
|
||||||
|
|
||||||
@@ -1962,7 +1962,7 @@ TEST_P(QuicServerTransportAllowMigrationTest, MigrateToUnvalidatedPeer) {
|
|||||||
deliverData(packetToBuf(packet), false, &newPeer);
|
deliverData(packetToBuf(packet), false, &newPeer);
|
||||||
EXPECT_FALSE(server->getConn().outstandingPathValidation);
|
EXPECT_FALSE(server->getConn().outstandingPathValidation);
|
||||||
EXPECT_FALSE(server->getConn().pendingEvents.schedulePathValidationTimeout);
|
EXPECT_FALSE(server->getConn().pendingEvents.schedulePathValidationTimeout);
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(&server->pathValidationTimeout()));
|
EXPECT_FALSE(server->pathValidationTimeout().isTimerCallbackScheduled());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(QuicServerTransportAllowMigrationTest, ResetPathRttPathResponse) {
|
TEST_P(QuicServerTransportAllowMigrationTest, ResetPathRttPathResponse) {
|
||||||
@@ -2008,7 +2008,7 @@ TEST_P(QuicServerTransportAllowMigrationTest, ResetPathRttPathResponse) {
|
|||||||
EXPECT_FALSE(server->getConn().pendingEvents.pathChallenge);
|
EXPECT_FALSE(server->getConn().pendingEvents.pathChallenge);
|
||||||
EXPECT_TRUE(server->getConn().outstandingPathValidation);
|
EXPECT_TRUE(server->getConn().outstandingPathValidation);
|
||||||
EXPECT_TRUE(server->getConn().pendingEvents.schedulePathValidationTimeout);
|
EXPECT_TRUE(server->getConn().pendingEvents.schedulePathValidationTimeout);
|
||||||
EXPECT_TRUE(qEvb_->isTimeoutScheduled(&server->pathValidationTimeout()));
|
EXPECT_TRUE(server->pathValidationTimeout().isTimerCallbackScheduled());
|
||||||
|
|
||||||
ShortHeader header(
|
ShortHeader header(
|
||||||
ProtectionType::KeyPhaseZero,
|
ProtectionType::KeyPhaseZero,
|
||||||
@@ -2028,7 +2028,7 @@ TEST_P(QuicServerTransportAllowMigrationTest, ResetPathRttPathResponse) {
|
|||||||
deliverData(packetToBuf(packet), false, &newPeer);
|
deliverData(packetToBuf(packet), false, &newPeer);
|
||||||
EXPECT_FALSE(server->getConn().outstandingPathValidation);
|
EXPECT_FALSE(server->getConn().outstandingPathValidation);
|
||||||
EXPECT_FALSE(server->getConn().pendingEvents.schedulePathValidationTimeout);
|
EXPECT_FALSE(server->getConn().pendingEvents.schedulePathValidationTimeout);
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(&server->pathValidationTimeout()));
|
EXPECT_FALSE(server->pathValidationTimeout().isTimerCallbackScheduled());
|
||||||
EXPECT_FALSE(server->getConn().writableBytesLimit);
|
EXPECT_FALSE(server->getConn().writableBytesLimit);
|
||||||
|
|
||||||
// After Pathresponse frame is received, srtt,lrtt = sampleRtt;
|
// After Pathresponse frame is received, srtt,lrtt = sampleRtt;
|
||||||
@@ -2076,7 +2076,7 @@ TEST_P(QuicServerTransportAllowMigrationTest, IgnoreInvalidPathResponse) {
|
|||||||
EXPECT_FALSE(server->getConn().pendingEvents.pathChallenge);
|
EXPECT_FALSE(server->getConn().pendingEvents.pathChallenge);
|
||||||
EXPECT_TRUE(server->getConn().outstandingPathValidation);
|
EXPECT_TRUE(server->getConn().outstandingPathValidation);
|
||||||
EXPECT_TRUE(server->getConn().pendingEvents.schedulePathValidationTimeout);
|
EXPECT_TRUE(server->getConn().pendingEvents.schedulePathValidationTimeout);
|
||||||
EXPECT_TRUE(qEvb_->isTimeoutScheduled(&server->pathValidationTimeout()));
|
EXPECT_TRUE(server->pathValidationTimeout().isTimerCallbackScheduled());
|
||||||
|
|
||||||
ShortHeader header(
|
ShortHeader header(
|
||||||
ProtectionType::KeyPhaseZero,
|
ProtectionType::KeyPhaseZero,
|
||||||
@@ -2097,7 +2097,7 @@ TEST_P(QuicServerTransportAllowMigrationTest, IgnoreInvalidPathResponse) {
|
|||||||
deliverData(packetToBuf(packet), false, &newPeer);
|
deliverData(packetToBuf(packet), false, &newPeer);
|
||||||
EXPECT_TRUE(server->getConn().outstandingPathValidation);
|
EXPECT_TRUE(server->getConn().outstandingPathValidation);
|
||||||
EXPECT_TRUE(server->getConn().pendingEvents.schedulePathValidationTimeout);
|
EXPECT_TRUE(server->getConn().pendingEvents.schedulePathValidationTimeout);
|
||||||
EXPECT_TRUE(qEvb_->isTimeoutScheduled(&server->pathValidationTimeout()));
|
EXPECT_TRUE(server->pathValidationTimeout().isTimerCallbackScheduled());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(
|
TEST_P(
|
||||||
@@ -2132,7 +2132,7 @@ TEST_P(
|
|||||||
EXPECT_FALSE(server->getConn().pendingEvents.pathChallenge);
|
EXPECT_FALSE(server->getConn().pendingEvents.pathChallenge);
|
||||||
EXPECT_TRUE(server->getConn().outstandingPathValidation);
|
EXPECT_TRUE(server->getConn().outstandingPathValidation);
|
||||||
EXPECT_TRUE(server->getConn().pendingEvents.schedulePathValidationTimeout);
|
EXPECT_TRUE(server->getConn().pendingEvents.schedulePathValidationTimeout);
|
||||||
EXPECT_TRUE(qEvb_->isTimeoutScheduled(&server->pathValidationTimeout()));
|
EXPECT_TRUE(server->pathValidationTimeout().isTimerCallbackScheduled());
|
||||||
|
|
||||||
EXPECT_TRUE(server->getConn().pathValidationLimiter != nullptr);
|
EXPECT_TRUE(server->getConn().pathValidationLimiter != nullptr);
|
||||||
|
|
||||||
@@ -2161,7 +2161,7 @@ TEST_P(
|
|||||||
EXPECT_TRUE(server->isClosed());
|
EXPECT_TRUE(server->isClosed());
|
||||||
EXPECT_TRUE(server->getConn().outstandingPathValidation);
|
EXPECT_TRUE(server->getConn().outstandingPathValidation);
|
||||||
EXPECT_FALSE(server->getConn().pendingEvents.schedulePathValidationTimeout);
|
EXPECT_FALSE(server->getConn().pendingEvents.schedulePathValidationTimeout);
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(&server->pathValidationTimeout()));
|
EXPECT_FALSE(server->pathValidationTimeout().isTimerCallbackScheduled());
|
||||||
|
|
||||||
EXPECT_TRUE(server->getConn().localConnectionError);
|
EXPECT_TRUE(server->getConn().localConnectionError);
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
@@ -2599,7 +2599,7 @@ TEST_F(
|
|||||||
EXPECT_TRUE(server->getConn().pendingEvents.pathChallenge);
|
EXPECT_TRUE(server->getConn().pendingEvents.pathChallenge);
|
||||||
EXPECT_FALSE(server->getConn().outstandingPathValidation);
|
EXPECT_FALSE(server->getConn().outstandingPathValidation);
|
||||||
EXPECT_FALSE(server->getConn().pendingEvents.schedulePathValidationTimeout);
|
EXPECT_FALSE(server->getConn().pendingEvents.schedulePathValidationTimeout);
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(&server->pathValidationTimeout()));
|
EXPECT_FALSE(server->pathValidationTimeout().isTimerCallbackScheduled());
|
||||||
|
|
||||||
EXPECT_EQ(server->getConn().migrationState.previousPeerAddresses.size(), 1);
|
EXPECT_EQ(server->getConn().migrationState.previousPeerAddresses.size(), 1);
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
@@ -2637,7 +2637,7 @@ TEST_F(
|
|||||||
EXPECT_FALSE(server->getConn().pendingEvents.pathChallenge);
|
EXPECT_FALSE(server->getConn().pendingEvents.pathChallenge);
|
||||||
EXPECT_FALSE(server->getConn().outstandingPathValidation);
|
EXPECT_FALSE(server->getConn().outstandingPathValidation);
|
||||||
EXPECT_FALSE(server->getConn().pendingEvents.schedulePathValidationTimeout);
|
EXPECT_FALSE(server->getConn().pendingEvents.schedulePathValidationTimeout);
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(&server->pathValidationTimeout()));
|
EXPECT_FALSE(server->pathValidationTimeout().isTimerCallbackScheduled());
|
||||||
|
|
||||||
EXPECT_EQ(server->getConn().migrationState.previousPeerAddresses.size(), 0);
|
EXPECT_EQ(server->getConn().migrationState.previousPeerAddresses.size(), 0);
|
||||||
EXPECT_EQ(server->getConn().lossState.srtt, srtt);
|
EXPECT_EQ(server->getConn().lossState.srtt, srtt);
|
||||||
@@ -2674,7 +2674,7 @@ TEST_F(
|
|||||||
EXPECT_EQ(server->getConn().peerAddress, newPeer);
|
EXPECT_EQ(server->getConn().peerAddress, newPeer);
|
||||||
EXPECT_TRUE(server->getConn().outstandingPathValidation);
|
EXPECT_TRUE(server->getConn().outstandingPathValidation);
|
||||||
EXPECT_TRUE(server->getConn().pendingEvents.schedulePathValidationTimeout);
|
EXPECT_TRUE(server->getConn().pendingEvents.schedulePathValidationTimeout);
|
||||||
EXPECT_TRUE(qEvb_->isTimeoutScheduled(&server->pathValidationTimeout()));
|
EXPECT_TRUE(server->pathValidationTimeout().isTimerCallbackScheduled());
|
||||||
|
|
||||||
EXPECT_EQ(server->getConn().migrationState.previousPeerAddresses.size(), 1);
|
EXPECT_EQ(server->getConn().migrationState.previousPeerAddresses.size(), 1);
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
@@ -2711,7 +2711,7 @@ TEST_F(
|
|||||||
deliverData(std::move(packetData2), false, &newPeer2);
|
deliverData(std::move(packetData2), false, &newPeer2);
|
||||||
EXPECT_FALSE(server->getConn().outstandingPathValidation);
|
EXPECT_FALSE(server->getConn().outstandingPathValidation);
|
||||||
EXPECT_FALSE(server->getConn().pendingEvents.schedulePathValidationTimeout);
|
EXPECT_FALSE(server->getConn().pendingEvents.schedulePathValidationTimeout);
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(&server->pathValidationTimeout()));
|
EXPECT_FALSE(server->pathValidationTimeout().isTimerCallbackScheduled());
|
||||||
|
|
||||||
EXPECT_EQ(server->getConn().migrationState.previousPeerAddresses.size(), 1);
|
EXPECT_EQ(server->getConn().migrationState.previousPeerAddresses.size(), 1);
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
@@ -2763,7 +2763,7 @@ TEST_F(
|
|||||||
EXPECT_EQ(server->getConn().peerAddress, newPeer);
|
EXPECT_EQ(server->getConn().peerAddress, newPeer);
|
||||||
EXPECT_TRUE(server->getConn().outstandingPathValidation);
|
EXPECT_TRUE(server->getConn().outstandingPathValidation);
|
||||||
EXPECT_TRUE(server->getConn().pendingEvents.schedulePathValidationTimeout);
|
EXPECT_TRUE(server->getConn().pendingEvents.schedulePathValidationTimeout);
|
||||||
EXPECT_TRUE(qEvb_->isTimeoutScheduled(&server->pathValidationTimeout()));
|
EXPECT_TRUE(server->pathValidationTimeout().isTimerCallbackScheduled());
|
||||||
|
|
||||||
EXPECT_EQ(server->getConn().migrationState.previousPeerAddresses.size(), 1);
|
EXPECT_EQ(server->getConn().migrationState.previousPeerAddresses.size(), 1);
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
@@ -2799,7 +2799,7 @@ TEST_F(
|
|||||||
deliverData(std::move(packetData2));
|
deliverData(std::move(packetData2));
|
||||||
EXPECT_FALSE(server->getConn().outstandingPathValidation);
|
EXPECT_FALSE(server->getConn().outstandingPathValidation);
|
||||||
EXPECT_FALSE(server->getConn().pendingEvents.schedulePathValidationTimeout);
|
EXPECT_FALSE(server->getConn().pendingEvents.schedulePathValidationTimeout);
|
||||||
EXPECT_FALSE(qEvb_->isTimeoutScheduled(&server->pathValidationTimeout()));
|
EXPECT_FALSE(server->pathValidationTimeout().isTimerCallbackScheduled());
|
||||||
|
|
||||||
EXPECT_EQ(server->getConn().migrationState.previousPeerAddresses.size(), 0);
|
EXPECT_EQ(server->getConn().migrationState.previousPeerAddresses.size(), 0);
|
||||||
EXPECT_EQ(server->getConn().lossState.srtt, srtt);
|
EXPECT_EQ(server->getConn().lossState.srtt, srtt);
|
||||||
|
@@ -88,7 +88,7 @@ class TestingQuicServerTransport : public QuicServerTransport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool isDraining() {
|
bool isDraining() {
|
||||||
return evb_->isTimeoutScheduled(&drainTimeout_);
|
return drainTimeout_.isTimerCallbackScheduled();
|
||||||
}
|
}
|
||||||
|
|
||||||
void triggerCryptoEvent() {
|
void triggerCryptoEvent() {
|
||||||
@@ -191,7 +191,7 @@ class QuicServerTransportTestBase : public virtual testing::Test {
|
|||||||
void startTransport() {
|
void startTransport() {
|
||||||
server->accept();
|
server->accept();
|
||||||
setupConnection();
|
setupConnection();
|
||||||
EXPECT_TRUE(qEvb_->isTimeoutScheduled(&server->idleTimeout()));
|
EXPECT_TRUE(server->idleTimeout().isTimerCallbackScheduled());
|
||||||
EXPECT_EQ(server->getConn().peerConnectionIds.size(), 1);
|
EXPECT_EQ(server->getConn().peerConnectionIds.size(), 1);
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
*server->getConn().clientConnectionId,
|
*server->getConn().clientConnectionId,
|
||||||
|
Reference in New Issue
Block a user