diff options
author | Mathias Agopian | 2017-03-27 19:59:01 -0500 |
---|---|---|
committer | Mathias Agopian | 2017-03-29 15:39:06 -0500 |
commit | 44cee05904fbedd41e8ab2b7d748e4db396ca7f2 (patch) | |
tree | 06bb46bb7d62d0dda823c1f49d2ce0d4e6bdb7e2 /libutils/include | |
parent | 8e16ceecb770df194ed7fb6ba70c01505a52a609 (diff) | |
download | platform-system-core-44cee05904fbedd41e8ab2b7d748e4db396ca7f2.tar.gz platform-system-core-44cee05904fbedd41e8ab2b7d748e4db396ca7f2.tar.xz platform-system-core-44cee05904fbedd41e8ab2b7d748e4db396ca7f2.zip |
split LightRefBase out of RefBase
Bug: 36532900
Test: compiled
Change-Id: I3088e1a219e04cf924744d3a0c2d374918bb6395
Diffstat (limited to 'libutils/include')
-rw-r--r-- | libutils/include/utils/LightRefBase.h | 72 | ||||
-rw-r--r-- | libutils/include/utils/RefBase.h | 75 |
2 files changed, 90 insertions, 57 deletions
diff --git a/libutils/include/utils/LightRefBase.h b/libutils/include/utils/LightRefBase.h new file mode 100644 index 000000000..65257edb9 --- /dev/null +++ b/libutils/include/utils/LightRefBase.h | |||
@@ -0,0 +1,72 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | #pragma once | ||
18 | |||
19 | /* | ||
20 | * See documentation in RefBase.h | ||
21 | */ | ||
22 | |||
23 | #include <atomic> | ||
24 | |||
25 | #include <sys/types.h> | ||
26 | |||
27 | namespace android { | ||
28 | |||
29 | class ReferenceRenamer; | ||
30 | |||
31 | template <class T> | ||
32 | class LightRefBase | ||
33 | { | ||
34 | public: | ||
35 | inline LightRefBase() : mCount(0) { } | ||
36 | inline void incStrong(__attribute__((unused)) const void* id) const { | ||
37 | mCount.fetch_add(1, std::memory_order_relaxed); | ||
38 | } | ||
39 | inline void decStrong(__attribute__((unused)) const void* id) const { | ||
40 | if (mCount.fetch_sub(1, std::memory_order_release) == 1) { | ||
41 | std::atomic_thread_fence(std::memory_order_acquire); | ||
42 | delete static_cast<const T*>(this); | ||
43 | } | ||
44 | } | ||
45 | //! DEBUGGING ONLY: Get current strong ref count. | ||
46 | inline int32_t getStrongCount() const { | ||
47 | return mCount.load(std::memory_order_relaxed); | ||
48 | } | ||
49 | |||
50 | typedef LightRefBase<T> basetype; | ||
51 | |||
52 | protected: | ||
53 | inline ~LightRefBase() { } | ||
54 | |||
55 | private: | ||
56 | friend class ReferenceMover; | ||
57 | inline static void renameRefs(size_t /*n*/, const ReferenceRenamer& /*renamer*/) { } | ||
58 | inline static void renameRefId(T* /*ref*/, const void* /*old_id*/ , const void* /*new_id*/) { } | ||
59 | |||
60 | private: | ||
61 | mutable std::atomic<int32_t> mCount; | ||
62 | }; | ||
63 | |||
64 | |||
65 | // This is a wrapper around LightRefBase that simply enforces a virtual | ||
66 | // destructor to eliminate the template requirement of LightRefBase | ||
67 | class VirtualLightRefBase : public LightRefBase<VirtualLightRefBase> { | ||
68 | public: | ||
69 | virtual ~VirtualLightRefBase() = default; | ||
70 | }; | ||
71 | |||
72 | }; // namespace android | ||
diff --git a/libutils/include/utils/RefBase.h b/libutils/include/utils/RefBase.h index a61ea58f4..223b6669d 100644 --- a/libutils/include/utils/RefBase.h +++ b/libutils/include/utils/RefBase.h | |||
@@ -177,6 +177,9 @@ | |||
177 | #include <stdlib.h> | 177 | #include <stdlib.h> |
178 | #include <string.h> | 178 | #include <string.h> |
179 | 179 | ||
180 | // LightRefBase used to be declared in this header, so we have to include it | ||
181 | #include <utils/LightRefBase.h> | ||
182 | |||
180 | #include <utils/StrongPointer.h> | 183 | #include <utils/StrongPointer.h> |
181 | #include <utils/TypeHelpers.h> | 184 | #include <utils/TypeHelpers.h> |
182 | 185 | ||
@@ -216,7 +219,7 @@ inline bool operator _op_ (const U* o) const { \ | |||
216 | 219 | ||
217 | class ReferenceRenamer { | 220 | class ReferenceRenamer { |
218 | protected: | 221 | protected: |
219 | // destructor is purposedly not virtual so we avoid code overhead from | 222 | // destructor is purposely not virtual so we avoid code overhead from |
220 | // subclasses; we have to make it protected to guarantee that it | 223 | // subclasses; we have to make it protected to guarantee that it |
221 | // cannot be called from this base class (and to make strict compilers | 224 | // cannot be called from this base class (and to make strict compilers |
222 | // happy). | 225 | // happy). |
@@ -246,13 +249,13 @@ public: | |||
246 | { | 249 | { |
247 | public: | 250 | public: |
248 | RefBase* refBase() const; | 251 | RefBase* refBase() const; |
249 | 252 | ||
250 | void incWeak(const void* id); | 253 | void incWeak(const void* id); |
251 | void decWeak(const void* id); | 254 | void decWeak(const void* id); |
252 | 255 | ||
253 | // acquires a strong reference if there is already one. | 256 | // acquires a strong reference if there is already one. |
254 | bool attemptIncStrong(const void* id); | 257 | bool attemptIncStrong(const void* id); |
255 | 258 | ||
256 | // acquires a weak reference if there is already one. | 259 | // acquires a weak reference if there is already one. |
257 | // This is not always safe. see ProcessState.cpp and BpBinder.cpp | 260 | // This is not always safe. see ProcessState.cpp and BpBinder.cpp |
258 | // for proper use. | 261 | // for proper use. |
@@ -268,12 +271,12 @@ public: | |||
268 | // enable -- enable/disable tracking | 271 | // enable -- enable/disable tracking |
269 | // retain -- when tracking is enable, if true, then we save a stack trace | 272 | // retain -- when tracking is enable, if true, then we save a stack trace |
270 | // for each reference and dereference; when retain == false, we | 273 | // for each reference and dereference; when retain == false, we |
271 | // match up references and dereferences and keep only the | 274 | // match up references and dereferences and keep only the |
272 | // outstanding ones. | 275 | // outstanding ones. |
273 | 276 | ||
274 | void trackMe(bool enable, bool retain); | 277 | void trackMe(bool enable, bool retain); |
275 | }; | 278 | }; |
276 | 279 | ||
277 | weakref_type* createWeak(const void* id) const; | 280 | weakref_type* createWeak(const void* id) const; |
278 | 281 | ||
279 | weakref_type* getWeakRefs() const; | 282 | weakref_type* getWeakRefs() const; |
@@ -345,54 +348,12 @@ private: | |||
345 | 348 | ||
346 | // --------------------------------------------------------------------------- | 349 | // --------------------------------------------------------------------------- |
347 | 350 | ||
348 | template <class T> | ||
349 | class LightRefBase | ||
350 | { | ||
351 | public: | ||
352 | inline LightRefBase() : mCount(0) { } | ||
353 | inline void incStrong(__attribute__((unused)) const void* id) const { | ||
354 | mCount.fetch_add(1, std::memory_order_relaxed); | ||
355 | } | ||
356 | inline void decStrong(__attribute__((unused)) const void* id) const { | ||
357 | if (mCount.fetch_sub(1, std::memory_order_release) == 1) { | ||
358 | std::atomic_thread_fence(std::memory_order_acquire); | ||
359 | delete static_cast<const T*>(this); | ||
360 | } | ||
361 | } | ||
362 | //! DEBUGGING ONLY: Get current strong ref count. | ||
363 | inline int32_t getStrongCount() const { | ||
364 | return mCount.load(std::memory_order_relaxed); | ||
365 | } | ||
366 | |||
367 | typedef LightRefBase<T> basetype; | ||
368 | |||
369 | protected: | ||
370 | inline ~LightRefBase() { } | ||
371 | |||
372 | private: | ||
373 | friend class ReferenceMover; | ||
374 | inline static void renameRefs(size_t /*n*/, const ReferenceRenamer& /*renamer*/) { } | ||
375 | inline static void renameRefId(T* /*ref*/, const void* /*old_id*/ , const void* /*new_id*/) { } | ||
376 | |||
377 | private: | ||
378 | mutable std::atomic<int32_t> mCount; | ||
379 | }; | ||
380 | |||
381 | // This is a wrapper around LightRefBase that simply enforces a virtual | ||
382 | // destructor to eliminate the template requirement of LightRefBase | ||
383 | class VirtualLightRefBase : public LightRefBase<VirtualLightRefBase> { | ||
384 | public: | ||
385 | virtual ~VirtualLightRefBase(); | ||
386 | }; | ||
387 | |||
388 | // --------------------------------------------------------------------------- | ||
389 | |||
390 | template <typename T> | 351 | template <typename T> |
391 | class wp | 352 | class wp |
392 | { | 353 | { |
393 | public: | 354 | public: |
394 | typedef typename RefBase::weakref_type weakref_type; | 355 | typedef typename RefBase::weakref_type weakref_type; |
395 | 356 | ||
396 | inline wp() : m_ptr(0) { } | 357 | inline wp() : m_ptr(0) { } |
397 | 358 | ||
398 | wp(T* other); // NOLINT(implicit) | 359 | wp(T* other); // NOLINT(implicit) |
@@ -403,31 +364,31 @@ public: | |||
403 | template<typename U> wp(const wp<U>& other); // NOLINT(implicit) | 364 | template<typename U> wp(const wp<U>& other); // NOLINT(implicit) |
404 | 365 | ||
405 | ~wp(); | 366 | ~wp(); |
406 | 367 | ||
407 | // Assignment | 368 | // Assignment |
408 | 369 | ||
409 | wp& operator = (T* other); | 370 | wp& operator = (T* other); |
410 | wp& operator = (const wp<T>& other); | 371 | wp& operator = (const wp<T>& other); |
411 | wp& operator = (const sp<T>& other); | 372 | wp& operator = (const sp<T>& other); |
412 | 373 | ||
413 | template<typename U> wp& operator = (U* other); | 374 | template<typename U> wp& operator = (U* other); |
414 | template<typename U> wp& operator = (const wp<U>& other); | 375 | template<typename U> wp& operator = (const wp<U>& other); |
415 | template<typename U> wp& operator = (const sp<U>& other); | 376 | template<typename U> wp& operator = (const sp<U>& other); |
416 | 377 | ||
417 | void set_object_and_refs(T* other, weakref_type* refs); | 378 | void set_object_and_refs(T* other, weakref_type* refs); |
418 | 379 | ||
419 | // promotion to sp | 380 | // promotion to sp |
420 | 381 | ||
421 | sp<T> promote() const; | 382 | sp<T> promote() const; |
422 | 383 | ||
423 | // Reset | 384 | // Reset |
424 | 385 | ||
425 | void clear(); | 386 | void clear(); |
426 | 387 | ||
427 | // Accessors | 388 | // Accessors |
428 | 389 | ||
429 | inline weakref_type* get_refs() const { return m_refs; } | 390 | inline weakref_type* get_refs() const { return m_refs; } |
430 | 391 | ||
431 | inline T* unsafe_get() const { return m_ptr; } | 392 | inline T* unsafe_get() const { return m_ptr; } |
432 | 393 | ||
433 | // Operators | 394 | // Operators |