mirror of
https://github.com/facebookincubator/mvfst.git
synced 2025-08-08 09:42:06 +03:00
QuicTransportBase: Allow notifyPendingWriteOnStream (#18)
Summary:
When a write callback x is already defined for a stream
and notifyPendingWriteOnStream is called with the same callback x,
it is safe to not return an error.
Building on master is currently broken due to 2040a13e40 (diff-ddd35d436da215e41b89fd5afe4acebbR11)
, but this commit builds when rebased before that.
udippant
Pull Request resolved: https://github.com/facebookincubator/mvfst/pull/18
Reviewed By: yangchi
Differential Revision: D15562893
Pulled By: afrind
fbshipit-source-id: 44e62bb9bb0002508257acdc419f20bcb973ca64
This commit is contained in:
committed by
Facebook Github Bot
parent
0b677465d0
commit
7d58058b8f
@@ -159,6 +159,7 @@ enum class LocalErrorCode : uint32_t {
|
||||
INVALID_OPERATION = 0x40000017,
|
||||
STREAM_LIMIT_EXCEEDED = 0x40000018,
|
||||
CONNECTION_ABANDONED = 0x40000019,
|
||||
CALLBACK_ALREADY_INSTALLED = 0x4000001A,
|
||||
};
|
||||
|
||||
using QuicErrorCode =
|
||||
|
@@ -84,6 +84,8 @@ std::string toString(LocalErrorCode code) {
|
||||
return "New version negotiatied";
|
||||
case LocalErrorCode::INVALID_WRITE_CALLBACK:
|
||||
return "Invalid write callback";
|
||||
case LocalErrorCode::CALLBACK_ALREADY_INSTALLED:
|
||||
return "Callback already installed";
|
||||
case LocalErrorCode::TLS_HANDSHAKE_FAILED:
|
||||
return "TLS handshake failed";
|
||||
case LocalErrorCode::APP_ERROR:
|
||||
|
@@ -1636,10 +1636,19 @@ QuicTransportBase::notifyPendingWriteOnStream(StreamId id, WriteCallback* wcb) {
|
||||
if (!qStream->writable()) {
|
||||
return folly::makeUnexpected(LocalErrorCode::STREAM_CLOSED);
|
||||
}
|
||||
|
||||
if (wcb == nullptr) {
|
||||
return folly::makeUnexpected(LocalErrorCode::INVALID_WRITE_CALLBACK);
|
||||
}
|
||||
// Add the callback to the pending write callbacks so that if we are closed
|
||||
// while we are scheduled in the loop, the close will error out the callbacks.
|
||||
if (!pendingWriteCallbacks_.emplace(id, wcb).second) {
|
||||
return folly::makeUnexpected(LocalErrorCode::INVALID_WRITE_CALLBACK);
|
||||
auto wcbEmplaceResult = pendingWriteCallbacks_.emplace(id, wcb);
|
||||
if (!wcbEmplaceResult.second) {
|
||||
if ((wcbEmplaceResult.first)->second != wcb) {
|
||||
return folly::makeUnexpected(LocalErrorCode::INVALID_WRITE_CALLBACK);
|
||||
} else {
|
||||
return folly::makeUnexpected(LocalErrorCode::CALLBACK_ALREADY_INSTALLED);
|
||||
}
|
||||
}
|
||||
runOnEvbAsync([id](auto self) {
|
||||
auto wcbIt = self->pendingWriteCallbacks_.find(id);
|
||||
|
@@ -1214,6 +1214,17 @@ TEST_P(QuicTransportImplTestClose, TestNotifyPendingConnWriteOnCloseWithError) {
|
||||
evb->loopOnce();
|
||||
}
|
||||
|
||||
TEST_F(QuicTransportImplTest, TestNotifyPendingWriteWithActiveCallback) {
|
||||
auto stream = transport->createBidirectionalStream().value();
|
||||
MockWriteCallback wcb;
|
||||
EXPECT_CALL(wcb, onStreamWriteReady(stream, _));
|
||||
auto ok1 = transport->notifyPendingWriteOnStream(stream, &wcb);
|
||||
EXPECT_TRUE(ok1.hasValue());
|
||||
auto ok2 = transport->notifyPendingWriteOnStream(stream, &wcb);
|
||||
EXPECT_EQ(ok2.error(), quic::LocalErrorCode::CALLBACK_ALREADY_INSTALLED);
|
||||
evb->loopOnce();
|
||||
}
|
||||
|
||||
TEST_F(QuicTransportImplTest, TestNotifyPendingWriteOnCloseWithoutError) {
|
||||
auto stream = transport->createBidirectionalStream().value();
|
||||
MockWriteCallback wcb;
|
||||
|
Reference in New Issue
Block a user