1 /*
2  *  Copyright (c) 2020 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 RTC_BASE_THREAD_MESSAGE_H_
11 #define RTC_BASE_THREAD_MESSAGE_H_
12 
13 #include <list>
14 #include <memory>
15 #include <utility>
16 
17 #include "api/scoped_refptr.h"
18 #include "rtc_base/location.h"
19 #include "rtc_base/message_handler.h"
20 
21 namespace rtc {
22 
23 // Derive from this for specialized data
24 // App manages lifetime, except when messages are purged
25 
26 class MessageData {
27  public:
MessageData()28   MessageData() {}
~MessageData()29   virtual ~MessageData() {}
30 };
31 
32 template <class T>
33 class TypedMessageData : public MessageData {
34  public:
TypedMessageData(const T & data)35   explicit TypedMessageData(const T& data) : data_(data) {}
data()36   const T& data() const { return data_; }
data()37   T& data() { return data_; }
38 
39  private:
40   T data_;
41 };
42 
43 // Like TypedMessageData, but for pointers that require a delete.
44 template <class T>
45 class ScopedMessageData : public MessageData {
46  public:
ScopedMessageData(std::unique_ptr<T> data)47   explicit ScopedMessageData(std::unique_ptr<T> data)
48       : data_(std::move(data)) {}
49   // Deprecated.
50   // TODO(deadbeef): Remove this once downstream applications stop using it.
ScopedMessageData(T * data)51   explicit ScopedMessageData(T* data) : data_(data) {}
52   // Deprecated.
53   // TODO(deadbeef): Returning a reference to a unique ptr? Why. Get rid of
54   // this once downstream applications stop using it, then rename inner_data to
55   // just data.
data()56   const std::unique_ptr<T>& data() const { return data_; }
data()57   std::unique_ptr<T>& data() { return data_; }
58 
inner_data()59   const T& inner_data() const { return *data_; }
inner_data()60   T& inner_data() { return *data_; }
61 
62  private:
63   std::unique_ptr<T> data_;
64 };
65 
66 // Like ScopedMessageData, but for reference counted pointers.
67 template <class T>
68 class ScopedRefMessageData : public MessageData {
69  public:
ScopedRefMessageData(T * data)70   explicit ScopedRefMessageData(T* data) : data_(data) {}
data()71   const scoped_refptr<T>& data() const { return data_; }
data()72   scoped_refptr<T>& data() { return data_; }
73 
74  private:
75   scoped_refptr<T> data_;
76 };
77 
78 template <class T>
WrapMessageData(const T & data)79 inline MessageData* WrapMessageData(const T& data) {
80   return new TypedMessageData<T>(data);
81 }
82 
83 template <class T>
UseMessageData(MessageData * data)84 inline const T& UseMessageData(MessageData* data) {
85   return static_cast<TypedMessageData<T>*>(data)->data();
86 }
87 
88 template <class T>
89 class DisposeData : public MessageData {
90  public:
DisposeData(T * data)91   explicit DisposeData(T* data) : data_(data) {}
~DisposeData()92   virtual ~DisposeData() { delete data_; }
93 
94  private:
95   T* data_;
96 };
97 
98 const uint32_t MQID_ANY = static_cast<uint32_t>(-1);
99 const uint32_t MQID_DISPOSE = static_cast<uint32_t>(-2);
100 
101 // No destructor
102 
103 struct Message {
MessageMessage104   Message() : phandler(nullptr), message_id(0), pdata(nullptr) {}
MatchMessage105   inline bool Match(MessageHandler* handler, uint32_t id) const {
106     return (handler == nullptr || handler == phandler) &&
107            (id == MQID_ANY || id == message_id);
108   }
109   Location posted_from;
110   MessageHandler* phandler;
111   uint32_t message_id;
112   MessageData* pdata;
113 };
114 
115 typedef std::list<Message> MessageList;
116 }  // namespace rtc
117 #endif  // RTC_BASE_THREAD_MESSAGE_H_
118