|
15 | 15 | */ |
16 | 16 |
|
17 | 17 | #include "base/fe_slice.h" |
| 18 | +#include <atomic> |
18 | 19 |
|
19 | 20 | namespace hybridse { |
20 | 21 | namespace base { |
21 | 22 |
|
22 | | -RefCountedSlice::~RefCountedSlice() { Release(); } |
| 23 | +RefCountedSlice::~RefCountedSlice() { _release(); } |
23 | 24 |
|
24 | | -void RefCountedSlice::Release() { |
| 25 | +void RefCountedSlice::_release() { |
25 | 26 | if (this->ref_cnt_ != nullptr) { |
26 | | - auto& cnt = *this->ref_cnt_; |
27 | | - cnt -= 1; |
28 | | - if (cnt == 0 && buf() != nullptr) { |
29 | | - // memset in case the buf is still used after free |
30 | | - memset(buf(), 0, size()); |
| 27 | + if (std::atomic_fetch_add_explicit(ref_cnt_, -1, std::memory_order_release) == 1) { |
| 28 | + std::atomic_thread_fence(std::memory_order_acquire); |
| 29 | + assert(buf()); |
31 | 30 | free(buf()); |
32 | 31 | delete this->ref_cnt_; |
33 | 32 | } |
34 | 33 | } |
35 | 34 | } |
36 | 35 |
|
37 | | -void RefCountedSlice::Update(const RefCountedSlice& slice) { |
| 36 | +void RefCountedSlice::_copy(const RefCountedSlice& slice) { |
38 | 37 | reset(slice.data(), slice.size()); |
39 | | - this->ref_cnt_ = slice.ref_cnt_; |
| 38 | + ref_cnt_ = slice.ref_cnt_; |
40 | 39 | if (this->ref_cnt_ != nullptr) { |
41 | | - (*this->ref_cnt_) += 1; |
| 40 | + std::atomic_fetch_add_explicit(ref_cnt_, 1, std::memory_order_relaxed); |
42 | 41 | } |
43 | 42 | } |
44 | 43 |
|
45 | | -RefCountedSlice::RefCountedSlice(const RefCountedSlice& slice) { |
46 | | - this->Update(slice); |
| 44 | +void RefCountedSlice::_swap(RefCountedSlice& slice) { |
| 45 | + std::swap(ref_cnt_, slice.ref_cnt_); |
| 46 | + Slice::_swap(slice); |
47 | 47 | } |
48 | 48 |
|
49 | | -RefCountedSlice::RefCountedSlice(RefCountedSlice&& slice) { |
50 | | - this->Update(slice); |
| 49 | +RefCountedSlice::RefCountedSlice(const RefCountedSlice& slice) { |
| 50 | + _copy(slice); |
51 | 51 | } |
52 | 52 |
|
| 53 | +RefCountedSlice::RefCountedSlice(RefCountedSlice&& slice) { _swap(slice); } |
| 54 | + |
53 | 55 | RefCountedSlice& RefCountedSlice::operator=(const RefCountedSlice& slice) { |
54 | 56 | if (&slice == this) { |
55 | 57 | return *this; |
56 | 58 | } |
57 | | - this->Release(); |
58 | | - this->Update(slice); |
| 59 | + _release(); |
| 60 | + _copy(slice); |
59 | 61 | return *this; |
60 | 62 | } |
61 | 63 |
|
62 | 64 | RefCountedSlice& RefCountedSlice::operator=(RefCountedSlice&& slice) { |
63 | | - if (&slice == this) { |
64 | | - return *this; |
65 | | - } |
66 | | - this->Release(); |
67 | | - this->Update(slice); |
| 65 | + _swap(slice); |
68 | 66 | return *this; |
69 | 67 | } |
70 | 68 |
|
|
0 commit comments