blob: c2c4d76c22aa0e75e0695b76916a1cd4f32f1ddf (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
|
/**************************************************************************
A/V Stream Camera Sample
Copyright (c) 2014, Microsoft Corporation.
File:
ref.h
Abstract:
Implement a reference counting base class. Also implement something
similar to ComPtr<>, called a CRefPtr<>. The implementation may not
be as robust as ComPtr<>, but it should do the job here.
History:
created 12/8/2014
**************************************************************************/
#pragma once
class CRef : public CNonCopyable
{
private:
EX_RUNDOWN_REF m_Rundown;
public:
// Initialize.
CRef()
{
Reset();
}
// Prevent deletion until the last reference is gone.
~CRef()
{
Wait();
}
// Increment the reference.
BOOLEAN
Acquire()
{
return ExAcquireRundownProtection( &m_Rundown );
}
// Decrement the reference.
void
Release()
{
return ExReleaseRundownProtection( &m_Rundown );
}
// Wait for the last reference to go away.
// Note: This must be called by the child object's destructor.
void
Wait()
{
ExWaitForRundownProtectionRelease( &m_Rundown );
}
// Reinitialize to reuse the associated object.
void
Reset()
{
ExInitializeRundownProtection( &m_Rundown );
}
};
template<class T>
class CRefPtr
{
private:
T *m_ptr;
public:
CRefPtr()
: m_ptr(nullptr)
{}
// Copy constructor.
CRefPtr( const CRefPtr<T> &ptr )
: m_ptr(nullptr)
{
// Make an initial assignment.
if( ptr && ptr->Acquire() )
{
m_ptr = ptr;
}
}
// Initial construction with a T object.
CRefPtr( T *ptr )
: m_ptr(nullptr)
{
// Make an initial assignment.
if( ptr && ptr->Acquire() )
{
m_ptr = ptr;
}
}
// Decrement the reference on destruction.
~CRefPtr()
{
// Free any ptr.
if( m_ptr )
{
m_ptr->Release();
}
}
// Assignment
CRefPtr<T> &
operator = ( T *ptr )
{
if( m_ptr )
{
m_ptr->Release();
}
if( ptr )
{
ptr->Acquire();
}
m_ptr = ptr;
return *this;
}
// Assignment
CRefPtr<T> &
operator = ( CRefPtr<T> &ptr )
{
return
(*this = ptr.m_ptr);
}
// Dereference the pointer.
T *
operator -> ()
{
return m_ptr;
}
// Test for nullptr.
operator bool()
{
return m_ptr != nullptr;
}
// Test for !nullptr.
bool
operator !()
{
return !m_ptr;
}
// Test for equality.
bool
operator ==( T *ptr )
{
return m_ptr == ptr;
}
// Unsafe accessor. Use sparingly.
T *
get()
{
return m_ptr;
}
};
// Test for equality.
template <class T>
inline
bool
operator ==( T *ptr1, CRefPtr<T> &ptr2 )
{
return ptr2 == ptr1;
}
|