summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/net/dcsctp/socket/callback_deferrer.cc
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--third_party/libwebrtc/net/dcsctp/socket/callback_deferrer.cc119
1 files changed, 63 insertions, 56 deletions
diff --git a/third_party/libwebrtc/net/dcsctp/socket/callback_deferrer.cc b/third_party/libwebrtc/net/dcsctp/socket/callback_deferrer.cc
index 0a24020167..549a592b8d 100644
--- a/third_party/libwebrtc/net/dcsctp/socket/callback_deferrer.cc
+++ b/third_party/libwebrtc/net/dcsctp/socket/callback_deferrer.cc
@@ -12,31 +12,6 @@
#include "api/make_ref_counted.h"
namespace dcsctp {
-namespace {
-// A wrapper around the move-only DcSctpMessage, to let it be captured in a
-// lambda.
-class MessageDeliverer {
- public:
- explicit MessageDeliverer(DcSctpMessage&& message)
- : state_(rtc::make_ref_counted<State>(std::move(message))) {}
-
- void Deliver(DcSctpSocketCallbacks& c) {
- // Really ensure that it's only called once.
- RTC_DCHECK(!state_->has_delivered);
- state_->has_delivered = true;
- c.OnMessageReceived(std::move(state_->message));
- }
-
- private:
- struct State : public webrtc::RefCountInterface {
- explicit State(DcSctpMessage&& m)
- : has_delivered(false), message(std::move(m)) {}
- bool has_delivered;
- DcSctpMessage message;
- };
- rtc::scoped_refptr<State> state_;
-};
-} // namespace
void CallbackDeferrer::Prepare() {
RTC_DCHECK(!prepared_);
@@ -48,12 +23,16 @@ void CallbackDeferrer::TriggerDeferred() {
// callback, and that might result in adding new callbacks to this instance,
// and the vector can't be modified while iterated on.
RTC_DCHECK(prepared_);
- std::vector<std::function<void(DcSctpSocketCallbacks & cb)>> deferred;
- deferred.swap(deferred_);
prepared_ = false;
-
- for (auto& cb : deferred) {
- cb(underlying_);
+ if (deferred_.empty()) {
+ return;
+ }
+ std::vector<std::pair<Callback, CallbackData>> deferred;
+ // Reserve a small buffer to prevent too much reallocation on growth.
+ deferred.reserve(8);
+ deferred.swap(deferred_);
+ for (auto& [cb, data] : deferred) {
+ cb(std::move(data), underlying_);
}
}
@@ -84,40 +63,57 @@ uint32_t CallbackDeferrer::GetRandomInt(uint32_t low, uint32_t high) {
void CallbackDeferrer::OnMessageReceived(DcSctpMessage message) {
RTC_DCHECK(prepared_);
deferred_.emplace_back(
- [deliverer = MessageDeliverer(std::move(message))](
- DcSctpSocketCallbacks& cb) mutable { deliverer.Deliver(cb); });
+ +[](CallbackData data, DcSctpSocketCallbacks& cb) {
+ return cb.OnMessageReceived(absl::get<DcSctpMessage>(std::move(data)));
+ },
+ std::move(message));
}
void CallbackDeferrer::OnError(ErrorKind error, absl::string_view message) {
RTC_DCHECK(prepared_);
deferred_.emplace_back(
- [error, message = std::string(message)](DcSctpSocketCallbacks& cb) {
- cb.OnError(error, message);
- });
+ +[](CallbackData data, DcSctpSocketCallbacks& cb) {
+ Error error = absl::get<Error>(std::move(data));
+ return cb.OnError(error.error, error.message);
+ },
+ Error{error, std::string(message)});
}
void CallbackDeferrer::OnAborted(ErrorKind error, absl::string_view message) {
RTC_DCHECK(prepared_);
deferred_.emplace_back(
- [error, message = std::string(message)](DcSctpSocketCallbacks& cb) {
- cb.OnAborted(error, message);
- });
+ +[](CallbackData data, DcSctpSocketCallbacks& cb) {
+ Error error = absl::get<Error>(std::move(data));
+ return cb.OnAborted(error.error, error.message);
+ },
+ Error{error, std::string(message)});
}
void CallbackDeferrer::OnConnected() {
RTC_DCHECK(prepared_);
- deferred_.emplace_back([](DcSctpSocketCallbacks& cb) { cb.OnConnected(); });
+ deferred_.emplace_back(
+ +[](CallbackData data, DcSctpSocketCallbacks& cb) {
+ return cb.OnConnected();
+ },
+ absl::monostate{});
}
void CallbackDeferrer::OnClosed() {
RTC_DCHECK(prepared_);
- deferred_.emplace_back([](DcSctpSocketCallbacks& cb) { cb.OnClosed(); });
+ deferred_.emplace_back(
+ +[](CallbackData data, DcSctpSocketCallbacks& cb) {
+ return cb.OnClosed();
+ },
+ absl::monostate{});
}
void CallbackDeferrer::OnConnectionRestarted() {
RTC_DCHECK(prepared_);
deferred_.emplace_back(
- [](DcSctpSocketCallbacks& cb) { cb.OnConnectionRestarted(); });
+ +[](CallbackData data, DcSctpSocketCallbacks& cb) {
+ return cb.OnConnectionRestarted();
+ },
+ absl::monostate{});
}
void CallbackDeferrer::OnStreamsResetFailed(
@@ -125,42 +121,53 @@ void CallbackDeferrer::OnStreamsResetFailed(
absl::string_view reason) {
RTC_DCHECK(prepared_);
deferred_.emplace_back(
- [streams = std::vector<StreamID>(outgoing_streams.begin(),
- outgoing_streams.end()),
- reason = std::string(reason)](DcSctpSocketCallbacks& cb) {
- cb.OnStreamsResetFailed(streams, reason);
- });
+ +[](CallbackData data, DcSctpSocketCallbacks& cb) {
+ StreamReset stream_reset = absl::get<StreamReset>(std::move(data));
+ return cb.OnStreamsResetFailed(stream_reset.streams,
+ stream_reset.message);
+ },
+ StreamReset{{outgoing_streams.begin(), outgoing_streams.end()},
+ std::string(reason)});
}
void CallbackDeferrer::OnStreamsResetPerformed(
rtc::ArrayView<const StreamID> outgoing_streams) {
RTC_DCHECK(prepared_);
deferred_.emplace_back(
- [streams = std::vector<StreamID>(outgoing_streams.begin(),
- outgoing_streams.end())](
- DcSctpSocketCallbacks& cb) { cb.OnStreamsResetPerformed(streams); });
+ +[](CallbackData data, DcSctpSocketCallbacks& cb) {
+ StreamReset stream_reset = absl::get<StreamReset>(std::move(data));
+ return cb.OnStreamsResetPerformed(stream_reset.streams);
+ },
+ StreamReset{{outgoing_streams.begin(), outgoing_streams.end()}});
}
void CallbackDeferrer::OnIncomingStreamsReset(
rtc::ArrayView<const StreamID> incoming_streams) {
RTC_DCHECK(prepared_);
deferred_.emplace_back(
- [streams = std::vector<StreamID>(incoming_streams.begin(),
- incoming_streams.end())](
- DcSctpSocketCallbacks& cb) { cb.OnIncomingStreamsReset(streams); });
+ +[](CallbackData data, DcSctpSocketCallbacks& cb) {
+ StreamReset stream_reset = absl::get<StreamReset>(std::move(data));
+ return cb.OnIncomingStreamsReset(stream_reset.streams);
+ },
+ StreamReset{{incoming_streams.begin(), incoming_streams.end()}});
}
void CallbackDeferrer::OnBufferedAmountLow(StreamID stream_id) {
RTC_DCHECK(prepared_);
- deferred_.emplace_back([stream_id](DcSctpSocketCallbacks& cb) {
- cb.OnBufferedAmountLow(stream_id);
- });
+ deferred_.emplace_back(
+ +[](CallbackData data, DcSctpSocketCallbacks& cb) {
+ return cb.OnBufferedAmountLow(absl::get<StreamID>(std::move(data)));
+ },
+ stream_id);
}
void CallbackDeferrer::OnTotalBufferedAmountLow() {
RTC_DCHECK(prepared_);
deferred_.emplace_back(
- [](DcSctpSocketCallbacks& cb) { cb.OnTotalBufferedAmountLow(); });
+ +[](CallbackData data, DcSctpSocketCallbacks& cb) {
+ return cb.OnTotalBufferedAmountLow();
+ },
+ absl::monostate{});
}
void CallbackDeferrer::OnLifecycleMessageExpired(LifecycleId lifecycle_id,