Agora C++ API Reference for All Platforms
Loading...
Searching...
No Matches
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
30namespace 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
48class 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
87
88template <class T, class Deleter = RefObjectDeleter>
89class 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
114 const agora::RefCountReleaseStatus status = ref_count_.DecRef();
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)
144template <typename T, typename... types>
145inline agora_refptr<T> make_refptr(types&&... args) {
146 return agora_refptr<T>(new RefCountedObject<T>(std::forward<types>(args)...));
147}
148#else
149template <typename T>
150inline agora_refptr<T> make_refptr() {
151 return agora_refptr<T>(new RefCountedObject<T>());
152}
153template <typename T, typename P0>
154inline agora_refptr<T> make_refptr(const P0& p0) {
155 return agora_refptr<T>(new RefCountedObject<T>(p0));
156}
157#endif
158} // namespace agora
static int Increment(volatile int *i)
Definition AgoraAtomicOps.h:27
static int AcquireLoad(volatile const int *i)
Definition AgoraAtomicOps.h:33
static int Decrement(volatile int *i)
Definition AgoraAtomicOps.h:30
Definition AgoraRefCountedObject.h:71
virtual agora::RefCountReleaseStatus Release() const
Definition AgoraRefCountedObjectInternal.h:113
RefCountedObject(P0 &&p0, P1 &&p1, Args &&... args)
Definition AgoraRefCountedObjectInternal.h:104
virtual bool HasOneRef() const
Definition AgoraRefCountedObjectInternal.h:129
agora::RefCounter ref_count_
Definition AgoraRefCountedObject.h:119
friend Deleter
Definition AgoraRefCountedObjectInternal.h:91
Deleter deleter_
Definition AgoraRefCountedObjectInternal.h:139
RefCountedObject(P0 &&p0)
Definition AgoraRefCountedObjectInternal.h:97
virtual ~RefCountedObject()
Definition AgoraRefCountedObjectInternal.h:132
virtual void AddRef() const
Definition AgoraRefCountedObjectInternal.h:111
RefCountedObject(const P0 &p0)
Definition AgoraRefCountedObjectInternal.h:99
RefCountedObject()
Definition AgoraRefCountedObjectInternal.h:93
Definition AgoraRefCountedObject.h:30
RefCounter(int ref_count)
Definition AgoraRefCountedObjectInternal.h:50
void IncRef()
Definition AgoraRefCountedObjectInternal.h:52
bool HasOneRef() const
Definition AgoraRefCountedObjectInternal.h:72
agora::RefCountReleaseStatus DecRef()
Definition AgoraRefCountedObjectInternal.h:58
Definition AgoraRefCountedObjectInternal.h:33
void operator()(const T *p) const
Definition AgoraRefCountedObjectInternal.h:36
Definition AgoraRefPtr.h:44
Definition AgoraAtomicOps.h:21
agora_refptr< T > make_refptr()
Definition AgoraRefCountedObject.h:129
OPTIONAL_ENUM_CLASS RefCountReleaseStatus
Definition AgoraRefPtr.h:25
Definition AgoraOptional.h:881