xref: /aosp_15_r20/external/webrtc/net/dcsctp/socket/callback_deferrer.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
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"
24 #include "api/task_queue/task_queue_base.h"
25 #include "net/dcsctp/public/dcsctp_message.h"
26 #include "net/dcsctp/public/dcsctp_socket.h"
27 
28 namespace dcsctp {
29 // 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.
44 class CallbackDeferrer : public DcSctpSocketCallbacks {
45  public:
46   class ScopedDeferrer {
47    public:
ScopedDeferrer(CallbackDeferrer & callback_deferrer)48     explicit ScopedDeferrer(CallbackDeferrer& callback_deferrer)
49         : callback_deferrer_(callback_deferrer) {
50       callback_deferrer_.Prepare();
51     }
52 
~ScopedDeferrer()53     ~ScopedDeferrer() { callback_deferrer_.TriggerDeferred(); }
54 
55    private:
56     CallbackDeferrer& callback_deferrer_;
57   };
58 
CallbackDeferrer(DcSctpSocketCallbacks & underlying)59   explicit CallbackDeferrer(DcSctpSocketCallbacks& underlying)
60       : underlying_(underlying) {}
61 
62   // Implementation of DcSctpSocketCallbacks
63   SendPacketStatus SendPacketWithStatus(
64       rtc::ArrayView<const uint8_t> data) override;
65   std::unique_ptr<Timeout> CreateTimeout(
66       webrtc::TaskQueueBase::DelayPrecision precision) override;
67   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;
75   void OnStreamsResetFailed(rtc::ArrayView<const StreamID> outgoing_streams,
76                             absl::string_view reason) override;
77   void OnStreamsResetPerformed(
78       rtc::ArrayView<const StreamID> outgoing_streams) override;
79   void OnIncomingStreamsReset(
80       rtc::ArrayView<const StreamID> incoming_streams) override;
81   void OnBufferedAmountLow(StreamID stream_id) override;
82   void OnTotalBufferedAmountLow() override;
83 
84   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 
90  private:
91   void Prepare();
92   void TriggerDeferred();
93 
94   DcSctpSocketCallbacks& underlying_;
95   bool prepared_ = false;
96   std::vector<std::function<void(DcSctpSocketCallbacks& cb)>> deferred_;
97 };
98 }  // namespace dcsctp
99 
100 #endif  // NET_DCSCTP_SOCKET_CALLBACK_DEFERRER_H_
101