Skip to content

Commit f45642c

Browse files
author
Donatien Garnier
committed
Make shared pointer thread safe and clean-up class and doc
1 parent 9ebfbc0 commit f45642c

File tree

1 file changed

+63
-31
lines changed

1 file changed

+63
-31
lines changed

platform/SharedPtr.h

Lines changed: 63 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,32 @@
2222
#include <stdint.h>
2323
#include <stddef.h>
2424

25+
#include "platform/mbed_critical.h"
26+
2527
/** Shared pointer class.
2628
*
27-
* Similar to std::shared_ptr in C++11.
29+
* A shared pointer is a "smart" pointer that retains ownership of an object using
30+
* reference counting accross all smart pointers referencing that object.
31+
*
32+
* @code
33+
* #include "platform/SharedPtr.h"
34+
*
35+
* struct MyStruct { int a; };
36+
*
37+
* // Create shared pointer
38+
* SharedPtr<MyStruct> ptr( new MyStruct );
39+
*
40+
* // Increase reference count
41+
* SharedPtr<MyStruct> ptr2( ptr );
42+
*
43+
* ptr =
44+
*
45+
* BLE& ble_interface = BLE::Instance();
46+
* @endcode
47+
*
48+
*
49+
* It is similar to the std::shared_ptr class introduced in C++11,
50+
* however this is not a compatible implementation (no weak pointer, no make_shared, no custom deleters, etc.)
2851
*
2952
* Usage: SharedPtr<class> POINTER(new class())
3053
*
@@ -43,37 +66,39 @@ class SharedPtr {
4366
* @brief Create empty SharedPtr not pointing to anything.
4467
* @details Used for variable declaration.
4568
*/
46-
SharedPtr(): pointer(NULL), counter(NULL) {
69+
SharedPtr(): _ptr(NULL), _counter(NULL) {
4770
}
4871

4972
/**
5073
* @brief Create new SharedPtr
51-
* @param _pointer Pointer to take control over
74+
* @param ptr Pointer to take control over
5275
*/
53-
SharedPtr(T* _pointer): pointer(_pointer) {
76+
SharedPtr(T* ptr): _ptr(ptr) {
5477
// allocate counter on the heap so it can be shared
55-
counter = (uint32_t*) malloc(sizeof(uint32_t));
56-
*counter = 1;
78+
_counter = (uint32_t*) malloc(sizeof(uint32_t));
79+
*_counter = 1;
5780
}
5881

5982
/**
6083
* @brief Destructor.
6184
* @details Decrement reference counter and delete object if no longer pointed to.
6285
*/
6386
~SharedPtr() {
64-
decrementCounter();
87+
decrement_counter();
6588
}
6689

6790
/**
6891
* @brief Copy constructor.
69-
* @details Create new SharePointer from other SharedPtr by
92+
* @details Create new SharedPtr from other SharedPtr by
7093
* copying pointer to original object and pointer to counter.
7194
* @param source Object being copied from.
7295
*/
73-
SharedPtr(const SharedPtr& source): pointer(source.pointer), counter(source.counter) {
96+
SharedPtr(const SharedPtr& source): _ptr(source._ptr), _counter(source._counter) {
7497
// increment reference counter
75-
if (counter) {
76-
(*counter)++;
98+
if (_counter) {
99+
core_util_critical_section_enter();
100+
(*_counter)++;
101+
core_util_critical_section_exit();
77102
}
78103
}
79104

@@ -86,15 +111,17 @@ class SharedPtr {
86111
SharedPtr operator=(const SharedPtr& source) {
87112
if (this != &source) {
88113
// clean up by decrementing counter
89-
decrementCounter();
114+
decrement_counter();
90115

91116
// assign new values
92-
pointer = source.get();
93-
counter = source.getCounter();
117+
_ptr = source.get();
118+
_counter = source.getCounter();
94119

95120
// increment new counter
96-
if (counter) {
97-
(*counter)++;
121+
if (_counter) {
122+
core_util_critical_section_enter();
123+
(*_counter)++;
124+
core_util_critical_section_exit();
98125
}
99126
}
100127

@@ -107,16 +134,18 @@ class SharedPtr {
107134
* @return Pointer.
108135
*/
109136
T* get() const {
110-
return pointer;
137+
return _ptr;
111138
}
112139

113140
/**
114141
* @brief Reference count accessor.
115142
* @return Reference count.
116143
*/
117144
uint32_t use_count() const {
118-
if (counter) {
119-
return *counter;
145+
if (_counter) {
146+
core_util_critical_section_enter();
147+
return *_counter;
148+
core_util_critical_section_exit();
120149
} else {
121150
return 0;
122151
}
@@ -127,23 +156,23 @@ class SharedPtr {
127156
* @details Override to return the object pointed to.
128157
*/
129158
T& operator*() const {
130-
return *pointer;
159+
return *_ptr;
131160
}
132161

133162
/**
134163
* @brief Dereference object member operator.
135164
* @details Override to return return member in object pointed to.
136165
*/
137166
T* operator->() const {
138-
return pointer;
167+
return _ptr;
139168
}
140169

141170
/**
142171
* @brief Boolean conversion operator.
143172
* @return Whether or not the pointer is NULL.
144173
*/
145174
operator bool() const {
146-
return (pointer != 0);
175+
return (_ptr != 0);
147176
}
148177

149178
private:
@@ -152,30 +181,33 @@ class SharedPtr {
152181
* @return Pointer to reference counter.
153182
*/
154183
uint32_t* getCounter() const {
155-
return counter;
184+
return _counter;
156185
}
157186

158187
/**
159188
* @brief Decrement reference counter.
160189
* @details If count reaches zero, free counter and delete object pointed to.
161190
*/
162-
void decrementCounter() {
163-
if (counter) {
164-
if (*counter == 1) {
165-
free(counter);
166-
delete pointer;
191+
void decrement_counter() {
192+
if (_counter) {
193+
core_util_critical_section_enter();
194+
if (*_counter == 1) {
195+
core_util_critical_section_exit();
196+
free(_counter);
197+
delete _ptr;
167198
} else {
168-
(*counter)--;
199+
(*_counter)--;
200+
core_util_critical_section_exit();
169201
}
170202
}
171203
}
172204

173205
private:
174206
// pointer to shared object
175-
T* pointer;
207+
T* _ptr;
176208

177209
// pointer to shared reference counter
178-
uint32_t* counter;
210+
uint32_t* _counter;
179211
};
180212

181213
/** Non-member relational operators.

0 commit comments

Comments
 (0)