Agora C++ API Reference for All Platforms
AgoraRefCountedObjectInternal.h
1 
2 // Copyright (c) 2020 Agora.io. All rights reserved
3 
4 // This program is confidential and proprietary to Agora.io.
5 // And may not be copied, reproduced, modified, disclosed to others, published
6 // or used, in whole or in part, without the express prior written permission
7 // of Agora.io.
8 #pragma once
9 
10 #include "AgoraRefPtr.h"
11 #include "api2/AgoraAtomicOps.h"
12 #include <api/aosl_mpq.h>
13 #include <api/cpp/aosl_ref_class.h>
14 
15 #ifndef __AGORA_REF_COUNTED_OBJECT_INTERNAL_H__
16 #define __AGORA_REF_COUNTED_OBJECT_INTERNAL_H__
17 #endif
18 
19 #if defined(__AGORA_REF_COUNTED_OBJECT_H__)
20 #error AgoraRefCountedObject is deprected now, its only purpose is for API compatiable. Consider using <api2/internal/AgoraRefCountedObjectInternal.h> instead.
21 #endif
22 
23 #ifndef OPTIONAL_REFCOUNTRELEASESTATUS_SPECIFIER
24 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
25 #define OPTIONAL_REFCOUNTRELEASESTATUS_SPECIFIER agora::RefCountReleaseStatus::
26 #else
27 #define OPTIONAL_REFCOUNTRELEASESTATUS_SPECIFIER
28 #endif
29 #endif
30 namespace agora {
31 
33 {
34  public:
35  template<class T>
36  void operator()(const T* p) const {
37  if(aosl_ref_class::run(aosl_mpq_main(), AOSL_REF_INVALID, __FUNCTION__, [p](const aosl_ts_t &queued_ts, aosl_refobj_t robj){
38  delete p;
39  }) < 0) {
40  /*
41  * main thread may not exist any more, delete in current thread context anyway.
42  */
43  delete p;
44  }
45  }
46 };
47 
48 class RefCounter {
49  public:
50  explicit RefCounter(int ref_count) : ref_count_(ref_count) {}
51 
52  void IncRef() { AtomicOps::Increment(&ref_count_); }
53 
59  return (AtomicOps::Decrement(&ref_count_) == 0
60  ? OPTIONAL_REFCOUNTRELEASESTATUS_SPECIFIER kDroppedLastRef
61  : OPTIONAL_REFCOUNTRELEASESTATUS_SPECIFIER kOtherRefsRemained);
62  }
63 
72  bool HasOneRef() const { return (AtomicOps::AcquireLoad(&ref_count_) == 1); }
73 
74  private:
75  RefCounter();
76 
77  private:
78  volatile int ref_count_;
79 };
80 
88 template <class T, class Deleter = RefObjectDeleter>
89 class RefCountedObject : public T {
90  public:
91  friend Deleter;
92 
94 
95  template <class P0>
96 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
97  explicit RefCountedObject(P0&& p0) : T(std::forward<P0>(p0)), ref_count_(0) {}
98 #else
99  explicit RefCountedObject(const P0& p0) : T(p0), ref_count_(0) {}
100 #endif
101 
102 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
103  template <class P0, class P1, class... Args>
104  RefCountedObject(P0&& p0, P1&& p1, Args&&... args)
105  : T(std::forward<P0>(p0),
106  std::forward<P1>(p1),
107  std::forward<Args>(args)...),
108  ref_count_(0) {}
109 #endif
110 
111  virtual void AddRef() const { ref_count_.IncRef(); }
112 
115  if (status == OPTIONAL_REFCOUNTRELEASESTATUS_SPECIFIER kDroppedLastRef) {
116  deleter_(this);
117  }
118  return status;
119  }
120 
129  virtual bool HasOneRef() const { return ref_count_.HasOneRef(); }
130 
131  protected:
132  virtual ~RefCountedObject() {}
133 
134  private:
136  RefCountedObject& operator=(const RefCountedObject&);
137 
138  protected:
141 };
142 
143 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
144 template <typename T, typename... types>
145 inline agora_refptr<T> make_refptr(types&&... args) {
146  return agora_refptr<T>(new RefCountedObject<T>(std::forward<types>(args)...));
147 }
148 #else
149 template <typename T>
150 inline agora_refptr<T> make_refptr() {
151  return agora_refptr<T>(new RefCountedObject<T>());
152 }
153 template <typename T, typename P0>
154 inline agora_refptr<T> make_refptr(const P0& p0) {
155  return agora_refptr<T>(new RefCountedObject<T>(p0));
156 }
157 #endif
158 } // namespace agora
agora::RefCountedObject::Release
virtual agora::RefCountReleaseStatus Release() const
Definition: AgoraRefCountedObjectInternal.h:113
agora::AtomicOps::AcquireLoad
static int AcquireLoad(volatile const int *i)
Definition: AgoraAtomicOps.h:33
agora::RefCountedObject::RefCountedObject
RefCountedObject(P0 &&p0, P1 &&p1, Args &&... args)
Definition: AgoraRefCountedObjectInternal.h:104
agora::agora_refptr
Definition: AgoraRefPtr.h:44
agora::make_refptr
agora_refptr< T > make_refptr(types &&... args)
Definition: AgoraRefCountedObject.h:124
agora::AtomicOps::Decrement
static int Decrement(volatile int *i)
Definition: AgoraAtomicOps.h:30
agora::RefCountedObject::HasOneRef
virtual bool HasOneRef() const
Definition: AgoraRefCountedObjectInternal.h:129
agora::RefObjectDeleter
Definition: AgoraRefCountedObjectInternal.h:33
agora::RefCountedObject::ref_count_
agora::RefCounter ref_count_
Definition: AgoraRefCountedObject.h:119
agora::RefCountedObject::RefCountedObject
RefCountedObject()
Definition: AgoraRefCountedObjectInternal.h:93
agora::RefCountedObject::AddRef
virtual void AddRef() const
Definition: AgoraRefCountedObjectInternal.h:111
agora::RefCountedObject
Definition: AgoraRefCountedObject.h:71
agora
Definition: AgoraAtomicOps.h:21
agora::AtomicOps::Increment
static int Increment(volatile int *i)
Definition: AgoraAtomicOps.h:27
agora::RefObjectDeleter::operator()
void operator()(const T *p) const
Definition: AgoraRefCountedObjectInternal.h:36
agora::RefCountedObject::RefCountedObject
RefCountedObject(const P0 &p0)
Definition: AgoraRefCountedObjectInternal.h:99
agora::RefCountedObject::RefCountedObject
RefCountedObject(P0 &&p0)
Definition: AgoraRefCountedObjectInternal.h:97
agora::RefCounter::IncRef
void IncRef()
Definition: AgoraRefCountedObjectInternal.h:52
agora::RefCountedObject::deleter_
Deleter deleter_
Definition: AgoraRefCountedObjectInternal.h:139
agora::RefCounter::HasOneRef
bool HasOneRef() const
Definition: AgoraRefCountedObjectInternal.h:72
std
Definition: AgoraOptional.h:881
agora::RefCountedObject::~RefCountedObject
virtual ~RefCountedObject()
Definition: AgoraRefCountedObjectInternal.h:132
agora::RefCounter
Definition: AgoraRefCountedObject.h:30
agora::RefCountReleaseStatus
OPTIONAL_ENUM_CLASS RefCountReleaseStatus
Definition: AgoraRefPtr.h:25
agora::RefCountedObject::Deleter
friend Deleter
Definition: AgoraRefCountedObjectInternal.h:91
agora::RefCounter::DecRef
agora::RefCountReleaseStatus DecRef()
Definition: AgoraRefCountedObjectInternal.h:58
agora::RefCounter::RefCounter
RefCounter(int ref_count)
Definition: AgoraRefCountedObjectInternal.h:50