mirror of
https://github.com/facebookincubator/mvfst.git
synced 2026-10-23 17:08:55 +03:00
Summary: Per-`QuicServer` `BatchWriterFactory` override so callers can plug in a custom `BatchWriter` for every connection a given server accepts. The override is stored on `QuicServer`, copied into each `QuicServerWorker`, stamped onto every accepted connection's `QuicConnectionStateBase` in `makeTransport`. Returning `nullptr` falls through; empty (the default) preserves existing behavior exactly. Two `QuicServer` instances can share a worker `EventBase` pool, so a thread or process-wide hook would silently last-writer-wins between them. Pinning the override on `QuicConnectionStateBase` keeps every connection routed through its owning server's factory. Also adds two small accessors the same upcoming `tperf` MSG_ZEROCOPY backend needs: `QuicServer::forEachListenerSocket` (walk per-worker listener fds for counter aggregation) and `folly::AsyncUDPSocket::drainErrMessages` (pump MSG_ERRQUEUE without subclassing). Mobile and MobileGSO factory variants get matching changes so all three factory build flavors compile. Promote `BatchWriterDeleter` in `quic/state/StateData.h` from a forward declaration to its full (empty) definition, and drop the now-duplicate definition from `quic/api/QuicBatchWriter.h`. The new `std::function<std::unique_ptr<BatchWriter, BatchWriterDeleter>(...)>` member added to `QuicConnectionStateBase` triggers `std::function`'s default constructor, which under libc++ eagerly instantiates `unique_ptr`'s `__compressed_pair<BatchWriter*, BatchWriterDeleter>` and its default `_CanBeEmptyBase = is_empty<D>::value && !__libcpp_is_final<D>::value` template argument. Those traits require D to be complete at every TU that instantiates `QuicConnectionStateBase`, which broke `buck build --flagfile fbcode//mode/libcxx fbcode//proxygen/facebook/revproxy:proxygenlib` while libstdc++ remained happy. Defining the deleter inline in the header (the struct is empty and its `operator()` body stays out-of-line in `QuicBatchWriterFactory*.cpp`) is the minimal fix and avoids creating an include cycle between `StateData.h` and `QuicBatchWriter.h`. Reviewed By: mjoras Differential Revision: D108459511 fbshipit-source-id: 00cf2fe35fc19ca0ab217d3dbf374c6fd89f957a
74 lines
2.1 KiB
C++
74 lines
2.1 KiB
C++
/*
|
|
* 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/api/QuicBatchWriterFactory.h>
|
|
#include <quic/api/QuicGsoBatchWriters.h>
|
|
|
|
namespace quic {
|
|
|
|
void BatchWriterDeleter::operator()(BatchWriter* batchWriter) {
|
|
delete batchWriter;
|
|
}
|
|
|
|
BatchWriterPtr makeGsoBatchWriter(uint32_t batchSize) {
|
|
return BatchWriterPtr(new GSOPacketBatchWriter(batchSize));
|
|
}
|
|
|
|
BatchWriterPtr makeGsoInPlaceBatchWriter(
|
|
uint32_t batchSize,
|
|
QuicConnectionStateBase& conn) {
|
|
return BatchWriterPtr(new GSOInplacePacketBatchWriter(conn, batchSize));
|
|
}
|
|
|
|
BatchWriterPtr makeSendmmsgGsoBatchWriter(uint32_t) {
|
|
return nullptr;
|
|
}
|
|
|
|
BatchWriterPtr makeSendmmsgInplaceGsoInplaceBatchWriter(
|
|
uint32_t,
|
|
QuicConnectionStateBase&) {
|
|
return nullptr;
|
|
}
|
|
|
|
BatchWriterPtr BatchWriterFactory::makeBatchWriter(
|
|
const quic::QuicBatchingMode& batchingMode,
|
|
uint32_t batchSize,
|
|
DataPathType dataPathType,
|
|
QuicConnectionStateBase& conn,
|
|
bool gsoSupported) {
|
|
if (conn.batchWriterFactoryOverride) {
|
|
auto batchWriter = conn.batchWriterFactoryOverride(
|
|
batchingMode, batchSize, dataPathType, conn, gsoSupported);
|
|
if (batchWriter) {
|
|
return batchWriter;
|
|
}
|
|
}
|
|
|
|
switch (batchingMode) {
|
|
case quic::QuicBatchingMode::BATCHING_MODE_GSO:
|
|
if (gsoSupported) {
|
|
if (dataPathType == DataPathType::ChainedMemory) {
|
|
return makeGsoBatchWriter(batchSize);
|
|
}
|
|
return makeGsoInPlaceBatchWriter(batchSize, conn);
|
|
}
|
|
// GSO unavailable on this device, fall through to single packet
|
|
[[fallthrough]];
|
|
case quic::QuicBatchingMode::BATCHING_MODE_NONE:
|
|
case quic::QuicBatchingMode::BATCHING_MODE_SENDMMSG:
|
|
case quic::QuicBatchingMode::BATCHING_MODE_SENDMMSG_GSO:
|
|
default:
|
|
// Default to single packet batching, ignoring batch size
|
|
if (dataPathType == DataPathType::ContinuousMemory) {
|
|
return BatchWriterPtr(new SinglePacketInplaceBatchWriter(conn));
|
|
}
|
|
return BatchWriterPtr(new SinglePacketBatchWriter());
|
|
}
|
|
}
|
|
|
|
} // namespace quic
|