aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Boehm <hboehm@google.com>2016-09-27 20:13:23 +0000
committerandroid-build-merger <android-build-merger@google.com>2016-09-27 20:13:23 +0000
commit66c2e2ce213a0d0fd1a457d1eb8526ea0af34c5f (patch)
treee6c74f004cb23a3e1d6073fd91112685b35c5957
parentfc3ce0b3307378905c8d8d74e71c233ca8226ba3 (diff)
parent0e90812b64239054c61b4a018d9ca559f8bb1658 (diff)
downloadskia-66c2e2ce213a0d0fd1a457d1eb8526ea0af34c5f.tar.gz
Make reference counted assignment check for races.
am: 0e90812b64 Change-Id: I18f2959367b0dc6779254b66e5088d44394cdb1f
-rw-r--r--include/core/SkRefCnt.h22
1 files changed, 22 insertions, 0 deletions
diff --git a/include/core/SkRefCnt.h b/include/core/SkRefCnt.h
index 9d1e5f1f02..422770c86d 100644
--- a/include/core/SkRefCnt.h
+++ b/include/core/SkRefCnt.h
@@ -136,6 +136,26 @@ class SK_API SkRefCnt : public SkRefCntBase { };
null in on each side of the assignment, and ensuring that ref() is called
before unref(), in case the two pointers point to the same object.
*/
+
+#if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) || defined(SK_DEBUG)
+// This version heuristically detects data races, since those otherwise result
+// in redundant reference count decrements, which are exceedingly
+// difficult to debug.
+
+#define SkRefCnt_SafeAssign(dst, src) \
+ do { \
+ typedef std::remove_reference<decltype(dst)>::type T; \
+ T old_dst = *const_cast<T volatile *>(&dst); \
+ if (src) src->ref(); \
+ if (old_dst) old_dst->unref(); \
+ if (old_dst != *const_cast<T volatile *>(&dst)) { \
+ SkDebugf("Detected racing Skia calls at %s:%d\n", __FILE__, __LINE__); \
+ } \
+ dst = src; \
+ } while (0)
+
+#else /* !(SK_BUILD_FOR_ANDROID_FRAMEWORK || SK_DEBUG) */
+
#define SkRefCnt_SafeAssign(dst, src) \
do { \
if (src) src->ref(); \
@@ -143,6 +163,8 @@ class SK_API SkRefCnt : public SkRefCntBase { };
dst = src; \
} while (0)
+#endif
+
/** Call obj->ref() and return obj. The obj must not be nullptr.
*/