1
0
mirror of https://github.com/facebookincubator/mvfst.git synced 2026-10-23 17:08:55 +03:00
Files
mvfst/quic/api/QuicBatchWriterFactoryMobileGSO.cpp
Joe Damato 7a75e45a43 mvfst: per-QuicServer BatchWriterFactory override hook
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
2026-06-26 17:23:18 -07:00

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