blob: 1c35dda6cf504ecbf1a80d4c9e7c942563e5d670 [file] [log] [blame]
Victor Boivieb6580cc2021-04-08 09:56:59 +02001/*
2 * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10#ifndef NET_DCSCTP_SOCKET_CALLBACK_DEFERRER_H_
11#define NET_DCSCTP_SOCKET_CALLBACK_DEFERRER_H_
12
13#include <cstdint>
14#include <functional>
15#include <memory>
16#include <string>
17#include <utility>
18#include <vector>
19
20#include "absl/strings/string_view.h"
21#include "api/array_view.h"
22#include "api/ref_counted_base.h"
23#include "api/scoped_refptr.h"
Henrik Boströmb951dc62022-01-26 18:38:13 +010024#include "api/task_queue/task_queue_base.h"
Victor Boivieb6580cc2021-04-08 09:56:59 +020025#include "net/dcsctp/public/dcsctp_message.h"
26#include "net/dcsctp/public/dcsctp_socket.h"
Victor Boivieb6580cc2021-04-08 09:56:59 +020027
28namespace dcsctp {
Victor Boivieb6580cc2021-04-08 09:56:59 +020029// Defers callbacks until they can be safely triggered.
30//
31// There are a lot of callbacks from the dcSCTP library to the client,
32// such as when messages are received or streams are closed. When the client
33// receives these callbacks, the client is expected to be able to call into the
34// library - from within the callback. For example, sending a reply message when
35// a certain SCTP message has been received, or to reconnect when the connection
36// was closed for any reason. This means that the dcSCTP library must always be
37// in a consistent and stable state when these callbacks are delivered, and to
38// ensure that's the case, callbacks are not immediately delivered from where
39// they originate, but instead queued (deferred) by this class. At the end of
40// any public API method that may result in callbacks, they are triggered and
41// then delivered.
42//
43// There are a number of exceptions, which is clearly annotated in the API.
44class CallbackDeferrer : public DcSctpSocketCallbacks {
45 public:
Victor Boivie15a0c882021-09-28 21:38:34 +020046 class ScopedDeferrer {
47 public:
48 explicit ScopedDeferrer(CallbackDeferrer& callback_deferrer)
49 : callback_deferrer_(callback_deferrer) {
50 callback_deferrer_.Prepare();
51 }
52
53 ~ScopedDeferrer() { callback_deferrer_.TriggerDeferred(); }
54
55 private:
56 CallbackDeferrer& callback_deferrer_;
57 };
58
Victor Boivieb6580cc2021-04-08 09:56:59 +020059 explicit CallbackDeferrer(DcSctpSocketCallbacks& underlying)
60 : underlying_(underlying) {}
61
Victor Boivie0081f1c2021-09-28 21:18:44 +020062 // Implementation of DcSctpSocketCallbacks
Victor Boivie8df32eb2021-08-12 15:21:25 +020063 SendPacketStatus SendPacketWithStatus(
Victor Boivie0081f1c2021-09-28 21:18:44 +020064 rtc::ArrayView<const uint8_t> data) override;
Henrik Boströmb951dc62022-01-26 18:38:13 +010065 std::unique_ptr<Timeout> CreateTimeout(
66 webrtc::TaskQueueBase::DelayPrecision precision) override;
Victor Boivie0081f1c2021-09-28 21:18:44 +020067 TimeMs TimeMillis() override;
68 uint32_t GetRandomInt(uint32_t low, uint32_t high) override;
69 void OnMessageReceived(DcSctpMessage message) override;
70 void OnError(ErrorKind error, absl::string_view message) override;
71 void OnAborted(ErrorKind error, absl::string_view message) override;
72 void OnConnected() override;
73 void OnClosed() override;
74 void OnConnectionRestarted() override;
Victor Boivieb6580cc2021-04-08 09:56:59 +020075 void OnStreamsResetFailed(rtc::ArrayView<const StreamID> outgoing_streams,
Victor Boivie0081f1c2021-09-28 21:18:44 +020076 absl::string_view reason) override;
Victor Boivieb6580cc2021-04-08 09:56:59 +020077 void OnStreamsResetPerformed(
Victor Boivie0081f1c2021-09-28 21:18:44 +020078 rtc::ArrayView<const StreamID> outgoing_streams) override;
Victor Boivieb6580cc2021-04-08 09:56:59 +020079 void OnIncomingStreamsReset(
Victor Boivie0081f1c2021-09-28 21:18:44 +020080 rtc::ArrayView<const StreamID> incoming_streams) override;
81 void OnBufferedAmountLow(StreamID stream_id) override;
82 void OnTotalBufferedAmountLow() override;
Victor Boivie236ac502021-05-20 19:34:18 +020083
Victor Boivie5e212622022-05-27 09:21:20 +020084 void OnLifecycleMessageExpired(LifecycleId lifecycle_id,
85 bool maybe_delivered) override;
86 void OnLifecycleMessageFullySent(LifecycleId lifecycle_id) override;
87 void OnLifecycleMessageDelivered(LifecycleId lifecycle_id) override;
88 void OnLifecycleEnd(LifecycleId lifecycle_id) override;
89
Victor Boivieb6580cc2021-04-08 09:56:59 +020090 private:
Victor Boivie15a0c882021-09-28 21:38:34 +020091 void Prepare();
92 void TriggerDeferred();
93
Victor Boivieb6580cc2021-04-08 09:56:59 +020094 DcSctpSocketCallbacks& underlying_;
Victor Boivie15a0c882021-09-28 21:38:34 +020095 bool prepared_ = false;
Victor Boivieb6580cc2021-04-08 09:56:59 +020096 std::vector<std::function<void(DcSctpSocketCallbacks& cb)>> deferred_;
97};
98} // namespace dcsctp
99
100#endif // NET_DCSCTP_SOCKET_CALLBACK_DEFERRER_H_