mirror of
https://github.com/facebookincubator/mvfst.git
synced 2025-08-08 09:42:06 +03:00
QuicEventBase wrapper
Summary: Create and use an actual wrapper around folly::EventBase. Later an interface will be added that the wrapper will be implementing. Reviewed By: jbeshay Differential Revision: D45822401 fbshipit-source-id: 3b33f796c31043ec2881b753a9b60943bdf91f1d
This commit is contained in:
committed by
Facebook GitHub Bot
parent
21de011c89
commit
dccfc706b5
@@ -36,6 +36,7 @@ add_dependencies(
|
|||||||
mvfst_codec_pktrebuilder
|
mvfst_codec_pktrebuilder
|
||||||
mvfst_codec_types
|
mvfst_codec_types
|
||||||
mvfst_constants
|
mvfst_constants
|
||||||
|
mvfst_events
|
||||||
mvfst_exception
|
mvfst_exception
|
||||||
mvfst_flowcontrol
|
mvfst_flowcontrol
|
||||||
mvfst_happyeyeballs
|
mvfst_happyeyeballs
|
||||||
@@ -65,6 +66,7 @@ target_link_libraries(
|
|||||||
mvfst_codec_pktrebuilder
|
mvfst_codec_pktrebuilder
|
||||||
mvfst_codec_types
|
mvfst_codec_types
|
||||||
mvfst_constants
|
mvfst_constants
|
||||||
|
mvfst_events
|
||||||
mvfst_exception
|
mvfst_exception
|
||||||
mvfst_flowcontrol
|
mvfst_flowcontrol
|
||||||
mvfst_happyeyeballs
|
mvfst_happyeyeballs
|
||||||
|
@@ -97,21 +97,22 @@ class ThreadLocalBatchWriterCache : public folly::AsyncTimeout {
|
|||||||
if (enabled_) {
|
if (enabled_) {
|
||||||
auto* evb = writer->evb();
|
auto* evb = writer->evb();
|
||||||
|
|
||||||
if (evb && !socket_) {
|
if (evb && evb->getBackingEventBase() && !socket_) {
|
||||||
auto fd = writer->getAndResetFd();
|
auto fd = writer->getAndResetFd();
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
socket_ = std::make_unique<folly::AsyncUDPSocket>(evb);
|
socket_ = std::make_unique<folly::AsyncUDPSocket>(
|
||||||
|
evb->getBackingEventBase());
|
||||||
socket_->setFD(
|
socket_->setFD(
|
||||||
folly::NetworkSocket(fd),
|
folly::NetworkSocket(fd),
|
||||||
folly::AsyncUDPSocket::FDOwnership::OWNS);
|
folly::AsyncUDPSocket::FDOwnership::OWNS);
|
||||||
}
|
}
|
||||||
attachTimeoutManager(evb);
|
attachTimeoutManager(evb->getBackingEventBase());
|
||||||
}
|
}
|
||||||
|
|
||||||
batchWriter_.reset(writer);
|
batchWriter_.reset(writer);
|
||||||
|
|
||||||
// start the timer if not active
|
// start the timer if not active
|
||||||
if (evb && socket_ && !timerActive_) {
|
if (evb && evb->getBackingEventBase() && socket_ && !timerActive_) {
|
||||||
addRef();
|
addRef();
|
||||||
timerActive_ = true;
|
timerActive_ = true;
|
||||||
evb->scheduleTimeoutHighRes(this, threadLocalDelay_);
|
evb->scheduleTimeoutHighRes(this, threadLocalDelay_);
|
||||||
|
@@ -25,14 +25,14 @@ class BatchWriter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setSock(folly::AsyncUDPSocket* sock) {
|
void setSock(folly::AsyncUDPSocket* sock) {
|
||||||
if (sock && !evb_) {
|
if (sock && !evb_.getBackingEventBase()) {
|
||||||
fd_ = ::dup(sock->getNetworkSocket().toFd());
|
fd_ = ::dup(sock->getNetworkSocket().toFd());
|
||||||
evb_ = sock->getEventBase();
|
evb_.setBackingEventBase(sock->getEventBase());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FOLLY_NODISCARD QuicEventBase* evb() const {
|
FOLLY_NODISCARD QuicEventBase* evb() {
|
||||||
return evb_;
|
return &evb_;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getAndResetFd() {
|
int getAndResetFd() {
|
||||||
@@ -67,7 +67,7 @@ class BatchWriter {
|
|||||||
const folly::SocketAddress& address) = 0;
|
const folly::SocketAddress& address) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QuicEventBase* evb_{nullptr};
|
QuicEventBase evb_;
|
||||||
int fd_{-1};
|
int fd_{-1};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -276,11 +276,12 @@ bool QuicStreamAsyncTransport::error() const {
|
|||||||
return bool(ex_);
|
return bool(ex_);
|
||||||
}
|
}
|
||||||
|
|
||||||
QuicEventBase* QuicStreamAsyncTransport::getEventBase() const {
|
folly::EventBase* QuicStreamAsyncTransport::getEventBase() const {
|
||||||
return sock_->getEventBase();
|
return sock_->getEventBase();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuicStreamAsyncTransport::attachEventBase(QuicEventBase* /*eventBase*/) {
|
void QuicStreamAsyncTransport::attachEventBase(
|
||||||
|
folly::EventBase* /*eventBase*/) {
|
||||||
LOG(FATAL) << "Does QUICSocket support this?";
|
LOG(FATAL) << "Does QUICSocket support this?";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -29,8 +29,7 @@ QuicTransportBase::QuicTransportBase(
|
|||||||
folly::EventBase* evb,
|
folly::EventBase* evb,
|
||||||
std::unique_ptr<folly::AsyncUDPSocket> socket,
|
std::unique_ptr<folly::AsyncUDPSocket> socket,
|
||||||
bool useConnectionEndWithErrorCallback)
|
bool useConnectionEndWithErrorCallback)
|
||||||
: evb_(evb),
|
: socket_(std::move(socket)),
|
||||||
socket_(std::move(socket)),
|
|
||||||
useConnectionEndWithErrorCallback_(useConnectionEndWithErrorCallback),
|
useConnectionEndWithErrorCallback_(useConnectionEndWithErrorCallback),
|
||||||
lossTimeout_(this),
|
lossTimeout_(this),
|
||||||
ackTimeout_(this),
|
ackTimeout_(this),
|
||||||
@@ -40,17 +39,19 @@ QuicTransportBase::QuicTransportBase(
|
|||||||
drainTimeout_(this),
|
drainTimeout_(this),
|
||||||
pingTimeout_(this),
|
pingTimeout_(this),
|
||||||
readLooper_(new FunctionLooper(
|
readLooper_(new FunctionLooper(
|
||||||
evb,
|
evb ? &qEvb_ : nullptr,
|
||||||
[this]() { invokeReadDataAndCallbacks(); },
|
[this]() { invokeReadDataAndCallbacks(); },
|
||||||
LooperType::ReadLooper)),
|
LooperType::ReadLooper)),
|
||||||
peekLooper_(new FunctionLooper(
|
peekLooper_(new FunctionLooper(
|
||||||
evb,
|
evb ? &qEvb_ : nullptr,
|
||||||
[this]() { invokePeekDataAndCallbacks(); },
|
[this]() { invokePeekDataAndCallbacks(); },
|
||||||
LooperType::PeekLooper)),
|
LooperType::PeekLooper)),
|
||||||
writeLooper_(new FunctionLooper(
|
writeLooper_(new FunctionLooper(
|
||||||
evb,
|
evb ? &qEvb_ : nullptr,
|
||||||
[this]() { pacedWriteDataToSocket(); },
|
[this]() { pacedWriteDataToSocket(); },
|
||||||
LooperType::WriteLooper)) {
|
LooperType::WriteLooper)) {
|
||||||
|
qEvbPtr_ = evb ? &qEvb_ : nullptr;
|
||||||
|
qEvb_.setBackingEventBase(evb);
|
||||||
writeLooper_->setPacingFunction([this]() -> auto {
|
writeLooper_->setPacingFunction([this]() -> auto {
|
||||||
if (isConnectionPaced(*conn_)) {
|
if (isConnectionPaced(*conn_)) {
|
||||||
return conn_->pacer->getTimeUntilNextWrite();
|
return conn_->pacer->getTimeUntilNextWrite();
|
||||||
@@ -79,7 +80,7 @@ void QuicTransportBase::setCongestionControllerFactory(
|
|||||||
}
|
}
|
||||||
|
|
||||||
folly::EventBase* QuicTransportBase::getEventBase() const {
|
folly::EventBase* QuicTransportBase::getEventBase() const {
|
||||||
return evb_.load();
|
return qEvb_.getBackingEventBase();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::shared_ptr<QLogger> QuicTransportBase::getQLogger() const {
|
const std::shared_ptr<QLogger> QuicTransportBase::getQLogger() const {
|
||||||
@@ -3387,7 +3388,8 @@ void QuicTransportBase::attachEventBase(folly::EventBase* evb) {
|
|||||||
VLOG(10) << __func__ << " " << *this;
|
VLOG(10) << __func__ << " " << *this;
|
||||||
DCHECK(!getEventBase());
|
DCHECK(!getEventBase());
|
||||||
DCHECK(evb && evb->isInEventBaseThread());
|
DCHECK(evb && evb->isInEventBaseThread());
|
||||||
evb_ = evb;
|
qEvb_.setBackingEventBase(evb);
|
||||||
|
qEvbPtr_ = &qEvb_;
|
||||||
if (socket_) {
|
if (socket_) {
|
||||||
socket_->attachEventBase(evb);
|
socket_->attachEventBase(evb);
|
||||||
}
|
}
|
||||||
@@ -3396,9 +3398,9 @@ void QuicTransportBase::attachEventBase(folly::EventBase* evb) {
|
|||||||
schedulePathValidationTimeout();
|
schedulePathValidationTimeout();
|
||||||
setIdleTimer();
|
setIdleTimer();
|
||||||
|
|
||||||
readLooper_->attachEventBase(evb);
|
readLooper_->attachEventBase(&qEvb_);
|
||||||
peekLooper_->attachEventBase(evb);
|
peekLooper_->attachEventBase(&qEvb_);
|
||||||
writeLooper_->attachEventBase(evb);
|
writeLooper_->attachEventBase(&qEvb_);
|
||||||
updateReadLooper();
|
updateReadLooper();
|
||||||
updatePeekLooper();
|
updatePeekLooper();
|
||||||
updateWriteLooper(false);
|
updateWriteLooper(false);
|
||||||
@@ -3409,8 +3411,8 @@ void QuicTransportBase::attachEventBase(folly::EventBase* evb) {
|
|||||||
SocketObserverInterface::Events::evbEvents>()) {
|
SocketObserverInterface::Events::evbEvents>()) {
|
||||||
getSocketObserverContainer()
|
getSocketObserverContainer()
|
||||||
->invokeInterfaceMethod<SocketObserverInterface::Events::evbEvents>(
|
->invokeInterfaceMethod<SocketObserverInterface::Events::evbEvents>(
|
||||||
[evb](auto observer, auto observed) {
|
[this](auto observer, auto observed) {
|
||||||
observer->evbAttach(observed, evb);
|
observer->evbAttach(observed, qEvb_.getBackingEventBase());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3439,12 +3441,13 @@ void QuicTransportBase::detachEventBase() {
|
|||||||
SocketObserverInterface::Events::evbEvents>()) {
|
SocketObserverInterface::Events::evbEvents>()) {
|
||||||
getSocketObserverContainer()
|
getSocketObserverContainer()
|
||||||
->invokeInterfaceMethod<SocketObserverInterface::Events::evbEvents>(
|
->invokeInterfaceMethod<SocketObserverInterface::Events::evbEvents>(
|
||||||
[evb = evb_.load()](auto observer, auto observed) {
|
[this](auto observer, auto observed) {
|
||||||
observer->evbDetach(observed, evb);
|
observer->evbDetach(observed, qEvb_.getBackingEventBase());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
evb_ = nullptr;
|
qEvb_.setBackingEventBase(nullptr);
|
||||||
|
qEvbPtr_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
folly::Optional<LocalErrorCode> QuicTransportBase::setControlStream(
|
folly::Optional<LocalErrorCode> QuicTransportBase::setControlStream(
|
||||||
|
@@ -840,7 +840,7 @@ class QuicTransportBase : public QuicSocket, QuicStreamPrioritiesObserver {
|
|||||||
*/
|
*/
|
||||||
folly::Optional<folly::SocketOptionMap> getAdditionalCmsgsForAsyncUDPSocket();
|
folly::Optional<folly::SocketOptionMap> getAdditionalCmsgsForAsyncUDPSocket();
|
||||||
|
|
||||||
std::atomic<QuicEventBase*> evb_;
|
std::atomic<QuicEventBase*> qEvbPtr_;
|
||||||
std::unique_ptr<folly::AsyncUDPSocket> socket_;
|
std::unique_ptr<folly::AsyncUDPSocket> socket_;
|
||||||
ConnectionSetupCallback* connSetupCallback_{nullptr};
|
ConnectionSetupCallback* connSetupCallback_{nullptr};
|
||||||
ConnectionCallback* connCallback_{nullptr};
|
ConnectionCallback* connCallback_{nullptr};
|
||||||
@@ -988,6 +988,9 @@ class QuicTransportBase : public QuicSocket, QuicStreamPrioritiesObserver {
|
|||||||
* additionalCmsgs callback
|
* additionalCmsgs callback
|
||||||
*/
|
*/
|
||||||
void updatePacketProcessorsPrewriteRequests();
|
void updatePacketProcessorsPrewriteRequests();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QuicEventBase qEvb_;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& os, const QuicTransportBase& qt);
|
std::ostream& operator<<(std::ostream& os, const QuicTransportBase& qt);
|
||||||
|
@@ -17,6 +17,7 @@ quic_add_test(TARGET QuicTransportTest
|
|||||||
DEPENDS
|
DEPENDS
|
||||||
Folly::folly
|
Folly::folly
|
||||||
mvfst_bufutil
|
mvfst_bufutil
|
||||||
|
mvfst_events
|
||||||
mvfst_transport
|
mvfst_transport
|
||||||
mvfst_server
|
mvfst_server
|
||||||
mvfst_state_stream_functions
|
mvfst_state_stream_functions
|
||||||
|
@@ -568,12 +568,16 @@ class TestQuicTransport
|
|||||||
class QuicTransportImplTest : public Test {
|
class QuicTransportImplTest : public Test {
|
||||||
public:
|
public:
|
||||||
void SetUp() override {
|
void SetUp() override {
|
||||||
evb = std::make_unique<QuicEventBase>();
|
backingEvb = std::make_unique<folly::EventBase>();
|
||||||
auto socket =
|
evb = std::make_unique<QuicEventBase>(backingEvb.get());
|
||||||
std::make_unique<NiceMock<folly::test::MockAsyncUDPSocket>>(evb.get());
|
auto socket = std::make_unique<NiceMock<folly::test::MockAsyncUDPSocket>>(
|
||||||
|
backingEvb.get());
|
||||||
socketPtr = socket.get();
|
socketPtr = socket.get();
|
||||||
transport = std::make_shared<TestQuicTransport>(
|
transport = std::make_shared<TestQuicTransport>(
|
||||||
evb.get(), std::move(socket), &connSetupCallback, &connCallback);
|
evb->getBackingEventBase(),
|
||||||
|
std::move(socket),
|
||||||
|
&connSetupCallback,
|
||||||
|
&connCallback);
|
||||||
auto& conn = *transport->transportConn;
|
auto& conn = *transport->transportConn;
|
||||||
conn.flowControlState.peerAdvertisedInitialMaxStreamOffsetBidiLocal =
|
conn.flowControlState.peerAdvertisedInitialMaxStreamOffsetBidiLocal =
|
||||||
kDefaultStreamWindowSize;
|
kDefaultStreamWindowSize;
|
||||||
@@ -601,6 +605,7 @@ class QuicTransportImplTest : public Test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
std::unique_ptr<folly::EventBase> backingEvb;
|
||||||
std::unique_ptr<QuicEventBase> evb;
|
std::unique_ptr<QuicEventBase> evb;
|
||||||
NiceMock<MockConnectionSetupCallback> connSetupCallback;
|
NiceMock<MockConnectionSetupCallback> connSetupCallback;
|
||||||
NiceMock<MockConnectionCallback> connCallback;
|
NiceMock<MockConnectionCallback> connCallback;
|
||||||
@@ -3104,7 +3109,7 @@ TEST_P(QuicTransportImplTestBase, GetLocalAddressUnboundSocket) {
|
|||||||
|
|
||||||
TEST_P(QuicTransportImplTestBase, GetLocalAddressBadSocket) {
|
TEST_P(QuicTransportImplTestBase, GetLocalAddressBadSocket) {
|
||||||
auto badTransport = std::make_shared<TestQuicTransport>(
|
auto badTransport = std::make_shared<TestQuicTransport>(
|
||||||
evb.get(), nullptr, &connSetupCallback, &connCallback);
|
evb->getBackingEventBase(), nullptr, &connSetupCallback, &connCallback);
|
||||||
badTransport->closeWithoutWrite();
|
badTransport->closeWithoutWrite();
|
||||||
SocketAddress localAddr = badTransport->getLocalAddress();
|
SocketAddress localAddr = badTransport->getLocalAddress();
|
||||||
EXPECT_FALSE(localAddr.isInitialized());
|
EXPECT_FALSE(localAddr.isInitialized());
|
||||||
@@ -4110,36 +4115,50 @@ TEST_P(QuicTransportImplTestBase, ObserverDetachAndAttachEvb) {
|
|||||||
transport->addObserver(obs3.get());
|
transport->addObserver(obs3.get());
|
||||||
|
|
||||||
// check the current event base and create a new one
|
// check the current event base and create a new one
|
||||||
EXPECT_EQ(evb.get(), transport->getEventBase());
|
EXPECT_EQ(evb->getBackingEventBase(), transport->getEventBase());
|
||||||
QuicEventBase evb2;
|
|
||||||
|
folly::EventBase backingEvb2;
|
||||||
|
QuicEventBase evb2(&backingEvb2);
|
||||||
|
|
||||||
// Detach the event base evb
|
// Detach the event base evb
|
||||||
EXPECT_CALL(*obs1, evbDetach(transport.get(), evb.get())).Times(0);
|
EXPECT_CALL(*obs1, evbDetach(transport.get(), evb->getBackingEventBase()))
|
||||||
EXPECT_CALL(*obs2, evbDetach(transport.get(), evb.get())).Times(1);
|
.Times(0);
|
||||||
EXPECT_CALL(*obs3, evbDetach(transport.get(), evb.get())).Times(1);
|
EXPECT_CALL(*obs2, evbDetach(transport.get(), evb->getBackingEventBase()))
|
||||||
|
.Times(1);
|
||||||
|
EXPECT_CALL(*obs3, evbDetach(transport.get(), evb->getBackingEventBase()))
|
||||||
|
.Times(1);
|
||||||
transport->detachEventBase();
|
transport->detachEventBase();
|
||||||
EXPECT_EQ(nullptr, transport->getEventBase());
|
EXPECT_EQ(nullptr, transport->getEventBase());
|
||||||
|
|
||||||
// Attach a new event base evb2
|
// Attach a new event base evb2
|
||||||
EXPECT_CALL(*obs1, evbAttach(transport.get(), &evb2)).Times(0);
|
EXPECT_CALL(*obs1, evbAttach(transport.get(), evb2.getBackingEventBase()))
|
||||||
EXPECT_CALL(*obs2, evbAttach(transport.get(), &evb2)).Times(1);
|
.Times(0);
|
||||||
EXPECT_CALL(*obs3, evbAttach(transport.get(), &evb2)).Times(1);
|
EXPECT_CALL(*obs2, evbAttach(transport.get(), evb2.getBackingEventBase()))
|
||||||
transport->attachEventBase(&evb2);
|
.Times(1);
|
||||||
EXPECT_EQ(&evb2, transport->getEventBase());
|
EXPECT_CALL(*obs3, evbAttach(transport.get(), evb2.getBackingEventBase()))
|
||||||
|
.Times(1);
|
||||||
|
transport->attachEventBase(evb2.getBackingEventBase());
|
||||||
|
EXPECT_EQ(evb2.getBackingEventBase(), transport->getEventBase());
|
||||||
|
|
||||||
// Detach the event base evb2
|
// Detach the event base evb2
|
||||||
EXPECT_CALL(*obs1, evbDetach(transport.get(), &evb2)).Times(0);
|
EXPECT_CALL(*obs1, evbDetach(transport.get(), evb2.getBackingEventBase()))
|
||||||
EXPECT_CALL(*obs2, evbDetach(transport.get(), &evb2)).Times(1);
|
.Times(0);
|
||||||
EXPECT_CALL(*obs3, evbDetach(transport.get(), &evb2)).Times(1);
|
EXPECT_CALL(*obs2, evbDetach(transport.get(), evb2.getBackingEventBase()))
|
||||||
|
.Times(1);
|
||||||
|
EXPECT_CALL(*obs3, evbDetach(transport.get(), evb2.getBackingEventBase()))
|
||||||
|
.Times(1);
|
||||||
transport->detachEventBase();
|
transport->detachEventBase();
|
||||||
EXPECT_EQ(nullptr, transport->getEventBase());
|
EXPECT_EQ(nullptr, transport->getEventBase());
|
||||||
|
|
||||||
// Attach the original event base evb
|
// Attach the original event base evb
|
||||||
EXPECT_CALL(*obs1, evbAttach(transport.get(), evb.get())).Times(0);
|
EXPECT_CALL(*obs1, evbAttach(transport.get(), evb->getBackingEventBase()))
|
||||||
EXPECT_CALL(*obs2, evbAttach(transport.get(), evb.get())).Times(1);
|
.Times(0);
|
||||||
EXPECT_CALL(*obs3, evbAttach(transport.get(), evb.get())).Times(1);
|
EXPECT_CALL(*obs2, evbAttach(transport.get(), evb->getBackingEventBase()))
|
||||||
transport->attachEventBase(evb.get());
|
.Times(1);
|
||||||
EXPECT_EQ(evb.get(), transport->getEventBase());
|
EXPECT_CALL(*obs3, evbAttach(transport.get(), evb->getBackingEventBase()))
|
||||||
|
.Times(1);
|
||||||
|
transport->attachEventBase(evb->getBackingEventBase());
|
||||||
|
EXPECT_EQ(evb->getBackingEventBase(), transport->getEventBase());
|
||||||
|
|
||||||
EXPECT_TRUE(transport->removeObserver(obs1.get()));
|
EXPECT_TRUE(transport->removeObserver(obs1.get()));
|
||||||
EXPECT_TRUE(transport->removeObserver(obs2.get()));
|
EXPECT_TRUE(transport->removeObserver(obs2.get()));
|
||||||
|
@@ -1558,7 +1558,7 @@ void QuicClientTransport::start(
|
|||||||
// TODO Supply v4 delay amount from somewhere when we want to tune this
|
// TODO Supply v4 delay amount from somewhere when we want to tune this
|
||||||
startHappyEyeballs(
|
startHappyEyeballs(
|
||||||
*clientConn_,
|
*clientConn_,
|
||||||
evb_,
|
qEvbPtr_,
|
||||||
happyEyeballsCachedFamily_,
|
happyEyeballsCachedFamily_,
|
||||||
happyEyeballsConnAttemptDelayTimeout_,
|
happyEyeballsConnAttemptDelayTimeout_,
|
||||||
happyEyeballsCachedFamily_ == AF_UNSPEC
|
happyEyeballsCachedFamily_ == AF_UNSPEC
|
||||||
|
@@ -70,6 +70,28 @@ target_link_libraries(
|
|||||||
Folly::folly
|
Folly::folly
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add_library(
|
||||||
|
mvfst_events STATIC
|
||||||
|
Events.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(
|
||||||
|
mvfst_events PUBLIC
|
||||||
|
$<BUILD_INTERFACE:${QUIC_FBCODE_ROOT}>
|
||||||
|
$<INSTALL_INTERFACE:include/>
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_options(
|
||||||
|
mvfst_events
|
||||||
|
PRIVATE
|
||||||
|
${_QUIC_COMMON_COMPILE_OPTIONS}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(
|
||||||
|
mvfst_events PUBLIC
|
||||||
|
Folly::folly
|
||||||
|
)
|
||||||
|
|
||||||
add_library(
|
add_library(
|
||||||
mvfst_socketutil STATIC
|
mvfst_socketutil STATIC
|
||||||
SocketUtil.cpp
|
SocketUtil.cpp
|
||||||
@@ -143,6 +165,12 @@ install(
|
|||||||
DESTINATION lib
|
DESTINATION lib
|
||||||
)
|
)
|
||||||
|
|
||||||
|
install(
|
||||||
|
TARGETS mvfst_events
|
||||||
|
EXPORT mvfst-exports
|
||||||
|
DESTINATION lib
|
||||||
|
)
|
||||||
|
|
||||||
install(
|
install(
|
||||||
TARGETS mvfst_socketutil
|
TARGETS mvfst_socketutil
|
||||||
EXPORT mvfst-exports
|
EXPORT mvfst-exports
|
||||||
|
73
quic/common/Events.cpp
Normal file
73
quic/common/Events.cpp
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* 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.h>
|
||||||
|
|
||||||
|
namespace quic {
|
||||||
|
|
||||||
|
void QuicEventBase::setBackingEventBase(folly::EventBase* evb) {
|
||||||
|
backingEvb_ = evb;
|
||||||
|
}
|
||||||
|
|
||||||
|
folly::EventBase* QuicEventBase::getBackingEventBase() const {
|
||||||
|
return backingEvb_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuicEventBase::runInLoop(LoopCallback* callback, bool thisIteration) {
|
||||||
|
return backingEvb_->runInLoop(callback, thisIteration);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuicEventBase::runInLoop(std::function<void()> cb, bool thisIteration) {
|
||||||
|
return backingEvb_->runInLoop(std::move(cb), thisIteration);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuicEventBase::runAfterDelay(
|
||||||
|
std::function<void()> cb,
|
||||||
|
uint32_t milliseconds) {
|
||||||
|
return backingEvb_->runAfterDelay(std::move(cb), milliseconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuicEventBase::runInEventBaseThreadAndWait(
|
||||||
|
std::function<void()> fn) noexcept {
|
||||||
|
return backingEvb_->runInEventBaseThreadAndWait(std::move(fn));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QuicEventBase::isInEventBaseThread() const {
|
||||||
|
return backingEvb_->isInEventBaseThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QuicEventBase::scheduleTimeoutHighRes(
|
||||||
|
folly::AsyncTimeout* obj,
|
||||||
|
std::chrono::microseconds timeout) {
|
||||||
|
return backingEvb_->scheduleTimeoutHighRes(obj, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
folly::HHWheelTimer& QuicEventBase::timer() {
|
||||||
|
return backingEvb_->timer();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QuicEventBase::loopOnce(int flags) {
|
||||||
|
return backingEvb_->loopOnce(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QuicEventBase::loop() {
|
||||||
|
return backingEvb_->loop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuicEventBase::loopForever() {
|
||||||
|
return backingEvb_->loopForever();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QuicEventBase::loopIgnoreKeepAlive() {
|
||||||
|
return backingEvb_->loopIgnoreKeepAlive();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuicEventBase::terminateLoopSoon() {
|
||||||
|
return backingEvb_->terminateLoopSoon();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace quic
|
@@ -8,9 +8,50 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <folly/io/async/EventBase.h>
|
#include <folly/io/async/EventBase.h>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
namespace quic {
|
namespace quic {
|
||||||
|
|
||||||
using QuicEventBase = folly::EventBase;
|
class QuicEventBase {
|
||||||
|
public:
|
||||||
|
QuicEventBase() = default;
|
||||||
|
explicit QuicEventBase(folly::EventBase* evb) : backingEvb_(evb) {}
|
||||||
|
virtual ~QuicEventBase() = default;
|
||||||
|
|
||||||
|
using LoopCallback = folly::EventBase::LoopCallback;
|
||||||
|
|
||||||
|
void setBackingEventBase(folly::EventBase* evb);
|
||||||
|
|
||||||
|
[[nodiscard]] folly::EventBase* getBackingEventBase() const;
|
||||||
|
|
||||||
|
void runInLoop(LoopCallback* callback, bool thisIteration = false);
|
||||||
|
|
||||||
|
void runInLoop(std::function<void()> cb, bool thisIteration = false);
|
||||||
|
|
||||||
|
void runAfterDelay(std::function<void()> cb, uint32_t milliseconds);
|
||||||
|
|
||||||
|
void runInEventBaseThreadAndWait(std::function<void()> fn) noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]] bool isInEventBaseThread() const;
|
||||||
|
|
||||||
|
bool scheduleTimeoutHighRes(
|
||||||
|
folly::AsyncTimeout* obj,
|
||||||
|
std::chrono::microseconds timeout);
|
||||||
|
|
||||||
|
folly::HHWheelTimer& timer();
|
||||||
|
|
||||||
|
bool loopOnce(int flags = 0);
|
||||||
|
|
||||||
|
bool loop();
|
||||||
|
|
||||||
|
void loopForever();
|
||||||
|
|
||||||
|
bool loopIgnoreKeepAlive();
|
||||||
|
|
||||||
|
void terminateLoopSoon();
|
||||||
|
|
||||||
|
private:
|
||||||
|
folly::EventBase* backingEvb_{nullptr};
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace quic
|
} // namespace quic
|
||||||
|
@@ -19,7 +19,8 @@ namespace test {
|
|||||||
class FunctionLooperTest : public Test {};
|
class FunctionLooperTest : public Test {};
|
||||||
|
|
||||||
TEST(FunctionLooperTest, LooperNotRunning) {
|
TEST(FunctionLooperTest, LooperNotRunning) {
|
||||||
EventBase evb;
|
EventBase backingEvb;
|
||||||
|
QuicEventBase evb(&backingEvb);
|
||||||
bool called = false;
|
bool called = false;
|
||||||
auto func = [&]() { called = true; };
|
auto func = [&]() { called = true; };
|
||||||
FunctionLooper::Ptr looper(
|
FunctionLooper::Ptr looper(
|
||||||
@@ -32,7 +33,8 @@ TEST(FunctionLooperTest, LooperNotRunning) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(FunctionLooperTest, LooperStarted) {
|
TEST(FunctionLooperTest, LooperStarted) {
|
||||||
EventBase evb;
|
EventBase backingEvb;
|
||||||
|
QuicEventBase evb(&backingEvb);
|
||||||
bool called = false;
|
bool called = false;
|
||||||
auto func = [&]() { called = true; };
|
auto func = [&]() { called = true; };
|
||||||
FunctionLooper::Ptr looper(
|
FunctionLooper::Ptr looper(
|
||||||
@@ -47,7 +49,8 @@ TEST(FunctionLooperTest, LooperStarted) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(FunctionLooperTest, LooperStopped) {
|
TEST(FunctionLooperTest, LooperStopped) {
|
||||||
EventBase evb;
|
EventBase backingEvb;
|
||||||
|
QuicEventBase evb(&backingEvb);
|
||||||
bool called = false;
|
bool called = false;
|
||||||
auto func = [&]() { called = true; };
|
auto func = [&]() { called = true; };
|
||||||
FunctionLooper::Ptr looper(
|
FunctionLooper::Ptr looper(
|
||||||
@@ -63,7 +66,8 @@ TEST(FunctionLooperTest, LooperStopped) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(FunctionLooperTest, LooperRestarted) {
|
TEST(FunctionLooperTest, LooperRestarted) {
|
||||||
EventBase evb;
|
EventBase backingEvb;
|
||||||
|
QuicEventBase evb(&backingEvb);
|
||||||
bool called = false;
|
bool called = false;
|
||||||
auto func = [&]() { called = true; };
|
auto func = [&]() { called = true; };
|
||||||
FunctionLooper::Ptr looper(
|
FunctionLooper::Ptr looper(
|
||||||
@@ -82,7 +86,8 @@ TEST(FunctionLooperTest, LooperRestarted) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(FunctionLooperTest, DestroyLooperDuringFunc) {
|
TEST(FunctionLooperTest, DestroyLooperDuringFunc) {
|
||||||
EventBase evb;
|
EventBase backingEvb;
|
||||||
|
QuicEventBase evb(&backingEvb);
|
||||||
bool called = false;
|
bool called = false;
|
||||||
FunctionLooper::Ptr* looperPtr = nullptr;
|
FunctionLooper::Ptr* looperPtr = nullptr;
|
||||||
|
|
||||||
@@ -101,7 +106,8 @@ TEST(FunctionLooperTest, DestroyLooperDuringFunc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(FunctionLooperTest, StopLooperDuringFunc) {
|
TEST(FunctionLooperTest, StopLooperDuringFunc) {
|
||||||
EventBase evb;
|
EventBase backingEvb;
|
||||||
|
QuicEventBase evb(&backingEvb);
|
||||||
bool called = false;
|
bool called = false;
|
||||||
FunctionLooper::Ptr* looperPtr = nullptr;
|
FunctionLooper::Ptr* looperPtr = nullptr;
|
||||||
|
|
||||||
@@ -122,7 +128,8 @@ TEST(FunctionLooperTest, StopLooperDuringFunc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(FunctionLooperTest, RunLooperDuringFunc) {
|
TEST(FunctionLooperTest, RunLooperDuringFunc) {
|
||||||
EventBase evb;
|
EventBase backingEvb;
|
||||||
|
QuicEventBase evb(&backingEvb);
|
||||||
bool called = false;
|
bool called = false;
|
||||||
FunctionLooper::Ptr* looperPtr = nullptr;
|
FunctionLooper::Ptr* looperPtr = nullptr;
|
||||||
|
|
||||||
@@ -143,7 +150,8 @@ TEST(FunctionLooperTest, RunLooperDuringFunc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(FunctionLooperTest, DetachStopsLooper) {
|
TEST(FunctionLooperTest, DetachStopsLooper) {
|
||||||
EventBase evb;
|
EventBase backingEvb;
|
||||||
|
QuicEventBase evb(&backingEvb);
|
||||||
bool called = false;
|
bool called = false;
|
||||||
auto func = [&]() { called = true; };
|
auto func = [&]() { called = true; };
|
||||||
FunctionLooper::Ptr looper(
|
FunctionLooper::Ptr looper(
|
||||||
@@ -157,8 +165,9 @@ TEST(FunctionLooperTest, DetachStopsLooper) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(FunctionLooperTest, PacingOnce) {
|
TEST(FunctionLooperTest, PacingOnce) {
|
||||||
EventBase evb;
|
EventBase backingEvb;
|
||||||
TimerHighRes::SharedPtr pacingTimer(TimerHighRes::newTimer(&evb, 1ms));
|
QuicEventBase evb(&backingEvb);
|
||||||
|
TimerHighRes::SharedPtr pacingTimer(TimerHighRes::newTimer(&backingEvb, 1ms));
|
||||||
int count = 0;
|
int count = 0;
|
||||||
auto func = [&]() { ++count; };
|
auto func = [&]() { ++count; };
|
||||||
bool firstTime = true;
|
bool firstTime = true;
|
||||||
@@ -183,8 +192,10 @@ TEST(FunctionLooperTest, PacingOnce) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(FunctionLooperTest, KeepPacing) {
|
TEST(FunctionLooperTest, KeepPacing) {
|
||||||
EventBase evb;
|
EventBase backingEvb;
|
||||||
TimerHighRes::SharedPtr pacingTimer(TimerHighRes::newTimer(&evb, 1ms));
|
QuicEventBase evb(&backingEvb);
|
||||||
|
TimerHighRes::SharedPtr pacingTimer(
|
||||||
|
TimerHighRes::newTimer(evb.getBackingEventBase(), 1ms));
|
||||||
int count = 0;
|
int count = 0;
|
||||||
auto func = [&]() { ++count; };
|
auto func = [&]() { ++count; };
|
||||||
bool stopPacing = false;
|
bool stopPacing = false;
|
||||||
@@ -226,8 +237,10 @@ TEST(FunctionLooperTest, KeepPacing) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(FunctionLooperTest, TimerTickSize) {
|
TEST(FunctionLooperTest, TimerTickSize) {
|
||||||
EventBase evb;
|
EventBase backingEvb;
|
||||||
TimerHighRes::SharedPtr pacingTimer(TimerHighRes::newTimer(&evb, 123ms));
|
QuicEventBase evb(&backingEvb);
|
||||||
|
TimerHighRes::SharedPtr pacingTimer(
|
||||||
|
TimerHighRes::newTimer(evb.getBackingEventBase(), 123ms));
|
||||||
FunctionLooper::Ptr looper(new FunctionLooper(
|
FunctionLooper::Ptr looper(new FunctionLooper(
|
||||||
&evb, [&]() {}, LooperType::ReadLooper));
|
&evb, [&]() {}, LooperType::ReadLooper));
|
||||||
looper->setPacingTimer(std::move(pacingTimer));
|
looper->setPacingTimer(std::move(pacingTimer));
|
||||||
@@ -235,21 +248,26 @@ TEST(FunctionLooperTest, TimerTickSize) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(FunctionLooperTest, TimerTickSizeAfterNewEvb) {
|
TEST(FunctionLooperTest, TimerTickSizeAfterNewEvb) {
|
||||||
EventBase evb;
|
EventBase backingEvb;
|
||||||
TimerHighRes::SharedPtr pacingTimer(TimerHighRes::newTimer(&evb, 123ms));
|
QuicEventBase evb(&backingEvb);
|
||||||
|
TimerHighRes::SharedPtr pacingTimer(
|
||||||
|
TimerHighRes::newTimer(evb.getBackingEventBase(), 123ms));
|
||||||
FunctionLooper::Ptr looper(new FunctionLooper(
|
FunctionLooper::Ptr looper(new FunctionLooper(
|
||||||
&evb, [&]() {}, LooperType::ReadLooper));
|
&evb, [&]() {}, LooperType::ReadLooper));
|
||||||
looper->setPacingTimer(std::move(pacingTimer));
|
looper->setPacingTimer(std::move(pacingTimer));
|
||||||
EXPECT_EQ(123ms, looper->getTimerTickInterval());
|
EXPECT_EQ(123ms, looper->getTimerTickInterval());
|
||||||
looper->detachEventBase();
|
looper->detachEventBase();
|
||||||
EventBase evb2;
|
EventBase backingEvb2;
|
||||||
|
QuicEventBase evb2(&backingEvb2);
|
||||||
looper->attachEventBase(&evb2);
|
looper->attachEventBase(&evb2);
|
||||||
EXPECT_EQ(123ms, looper->getTimerTickInterval());
|
EXPECT_EQ(123ms, looper->getTimerTickInterval());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(FunctionLooperTest, NoLoopCallbackInPacingMode) {
|
TEST(FunctionLooperTest, NoLoopCallbackInPacingMode) {
|
||||||
EventBase evb;
|
EventBase backingEvb;
|
||||||
TimerHighRes::SharedPtr pacingTimer(TimerHighRes::newTimer(&evb, 1ms));
|
QuicEventBase evb(&backingEvb);
|
||||||
|
TimerHighRes::SharedPtr pacingTimer(
|
||||||
|
TimerHighRes::newTimer(evb.getBackingEventBase(), 1ms));
|
||||||
auto runFunc = [&]() {};
|
auto runFunc = [&]() {};
|
||||||
auto pacingFunc = [&]() { return 3600000ms; };
|
auto pacingFunc = [&]() { return 3600000ms; };
|
||||||
FunctionLooper::Ptr looper(
|
FunctionLooper::Ptr looper(
|
||||||
|
@@ -194,7 +194,9 @@ void QuicServerTransport::accept() {
|
|||||||
updateFlowControlStateWithSettings(
|
updateFlowControlStateWithSettings(
|
||||||
conn_->flowControlState, conn_->transportSettings);
|
conn_->flowControlState, conn_->transportSettings);
|
||||||
serverConn_->serverHandshakeLayer->initialize(
|
serverConn_->serverHandshakeLayer->initialize(
|
||||||
evb_, this, std::make_unique<DefaultAppTokenValidator>(serverConn_));
|
qEvbPtr_.load()->getBackingEventBase(),
|
||||||
|
this,
|
||||||
|
std::make_unique<DefaultAppTokenValidator>(serverConn_));
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuicServerTransport::writeData() {
|
void QuicServerTransport::writeData() {
|
||||||
|
Reference in New Issue
Block a user