1554875210043b34178f7ed6ac5bd682b1fad367bbungeman@google.com/* 2554875210043b34178f7ed6ac5bd682b1fad367bbungeman@google.com * Copyright 2012 Google Inc. 3554875210043b34178f7ed6ac5bd682b1fad367bbungeman@google.com * 4554875210043b34178f7ed6ac5bd682b1fad367bbungeman@google.com * Use of this source code is governed by a BSD-style license that can be 5554875210043b34178f7ed6ac5bd682b1fad367bbungeman@google.com * found in the LICENSE file. 6554875210043b34178f7ed6ac5bd682b1fad367bbungeman@google.com */ 7554875210043b34178f7ed6ac5bd682b1fad367bbungeman@google.com 8554875210043b34178f7ed6ac5bd682b1fad367bbungeman@google.com#include "SkRefCnt.h" 9e4fafb146e85cdfcf9d5418597b6818aa0754adatfarina@chromium.org#include "SkTypes.h" 10a02bc1519cf49afa31fb38bed097dd5014880d04bungeman@google.com#include "SkWeakRefCnt.h" 118f6884aab8aecd7657cf3f9cdbc682f0deca29c5tfarina@chromium.org#include "Test.h" 1203141d25cf75c4ce6cdb94f90e9538ee3c878699Mike Klein#include <thread> 13554875210043b34178f7ed6ac5bd682b1fad367bbungeman@google.com 14554875210043b34178f7ed6ac5bd682b1fad367bbungeman@google.comstatic void bounce_ref(void* data) { 15554875210043b34178f7ed6ac5bd682b1fad367bbungeman@google.com SkRefCnt* ref = static_cast<SkRefCnt*>(data); 16554875210043b34178f7ed6ac5bd682b1fad367bbungeman@google.com for (int i = 0; i < 100000; ++i) { 17554875210043b34178f7ed6ac5bd682b1fad367bbungeman@google.com ref->ref(); 18554875210043b34178f7ed6ac5bd682b1fad367bbungeman@google.com ref->unref(); 19554875210043b34178f7ed6ac5bd682b1fad367bbungeman@google.com } 20554875210043b34178f7ed6ac5bd682b1fad367bbungeman@google.com} 21554875210043b34178f7ed6ac5bd682b1fad367bbungeman@google.com 22554875210043b34178f7ed6ac5bd682b1fad367bbungeman@google.comstatic void test_refCnt(skiatest::Reporter* reporter) { 23554875210043b34178f7ed6ac5bd682b1fad367bbungeman@google.com SkRefCnt* ref = new SkRefCnt(); 24554875210043b34178f7ed6ac5bd682b1fad367bbungeman@google.com 2503141d25cf75c4ce6cdb94f90e9538ee3c878699Mike Klein std::thread thing1(bounce_ref, ref); 2603141d25cf75c4ce6cdb94f90e9538ee3c878699Mike Klein std::thread thing2(bounce_ref, ref); 27554875210043b34178f7ed6ac5bd682b1fad367bbungeman@google.com 28554875210043b34178f7ed6ac5bd682b1fad367bbungeman@google.com thing1.join(); 29554875210043b34178f7ed6ac5bd682b1fad367bbungeman@google.com thing2.join(); 30554875210043b34178f7ed6ac5bd682b1fad367bbungeman@google.com 31bbb61d7268b26d240afde2c924cb7d1370aa4071mtklein REPORTER_ASSERT(reporter, ref->unique()); 32554875210043b34178f7ed6ac5bd682b1fad367bbungeman@google.com ref->unref(); 33554875210043b34178f7ed6ac5bd682b1fad367bbungeman@google.com} 34554875210043b34178f7ed6ac5bd682b1fad367bbungeman@google.com 35a02bc1519cf49afa31fb38bed097dd5014880d04bungeman@google.comstatic void bounce_weak_ref(void* data) { 36a02bc1519cf49afa31fb38bed097dd5014880d04bungeman@google.com SkWeakRefCnt* ref = static_cast<SkWeakRefCnt*>(data); 37a02bc1519cf49afa31fb38bed097dd5014880d04bungeman@google.com for (int i = 0; i < 100000; ++i) { 38a02bc1519cf49afa31fb38bed097dd5014880d04bungeman@google.com if (ref->try_ref()) { 39a02bc1519cf49afa31fb38bed097dd5014880d04bungeman@google.com ref->unref(); 40a02bc1519cf49afa31fb38bed097dd5014880d04bungeman@google.com } 41a02bc1519cf49afa31fb38bed097dd5014880d04bungeman@google.com } 42a02bc1519cf49afa31fb38bed097dd5014880d04bungeman@google.com} 43a02bc1519cf49afa31fb38bed097dd5014880d04bungeman@google.com 44a02bc1519cf49afa31fb38bed097dd5014880d04bungeman@google.comstatic void bounce_weak_weak_ref(void* data) { 45a02bc1519cf49afa31fb38bed097dd5014880d04bungeman@google.com SkWeakRefCnt* ref = static_cast<SkWeakRefCnt*>(data); 46a02bc1519cf49afa31fb38bed097dd5014880d04bungeman@google.com for (int i = 0; i < 100000; ++i) { 47a02bc1519cf49afa31fb38bed097dd5014880d04bungeman@google.com ref->weak_ref(); 48a02bc1519cf49afa31fb38bed097dd5014880d04bungeman@google.com ref->weak_unref(); 49a02bc1519cf49afa31fb38bed097dd5014880d04bungeman@google.com } 50a02bc1519cf49afa31fb38bed097dd5014880d04bungeman@google.com} 51a02bc1519cf49afa31fb38bed097dd5014880d04bungeman@google.com 52a02bc1519cf49afa31fb38bed097dd5014880d04bungeman@google.comstatic void test_weakRefCnt(skiatest::Reporter* reporter) { 53a02bc1519cf49afa31fb38bed097dd5014880d04bungeman@google.com SkWeakRefCnt* ref = new SkWeakRefCnt(); 54a02bc1519cf49afa31fb38bed097dd5014880d04bungeman@google.com 5503141d25cf75c4ce6cdb94f90e9538ee3c878699Mike Klein std::thread thing1(bounce_ref, ref); 5603141d25cf75c4ce6cdb94f90e9538ee3c878699Mike Klein std::thread thing2(bounce_ref, ref); 5703141d25cf75c4ce6cdb94f90e9538ee3c878699Mike Klein std::thread thing3(bounce_weak_ref, ref); 5803141d25cf75c4ce6cdb94f90e9538ee3c878699Mike Klein std::thread thing4(bounce_weak_weak_ref, ref); 59a02bc1519cf49afa31fb38bed097dd5014880d04bungeman@google.com 60a02bc1519cf49afa31fb38bed097dd5014880d04bungeman@google.com thing1.join(); 61a02bc1519cf49afa31fb38bed097dd5014880d04bungeman@google.com thing2.join(); 62a02bc1519cf49afa31fb38bed097dd5014880d04bungeman@google.com thing3.join(); 63a02bc1519cf49afa31fb38bed097dd5014880d04bungeman@google.com thing4.join(); 64a02bc1519cf49afa31fb38bed097dd5014880d04bungeman@google.com 65bbb61d7268b26d240afde2c924cb7d1370aa4071mtklein REPORTER_ASSERT(reporter, ref->unique()); 662c4bd0798e929acb9663668985eabe74d7378c46bungeman SkDEBUGCODE(REPORTER_ASSERT(reporter, ref->getWeakCnt() == 1)); 67a02bc1519cf49afa31fb38bed097dd5014880d04bungeman@google.com ref->unref(); 68a02bc1519cf49afa31fb38bed097dd5014880d04bungeman@google.com} 69a02bc1519cf49afa31fb38bed097dd5014880d04bungeman@google.com 70e4fafb146e85cdfcf9d5418597b6818aa0754adatfarina@chromium.orgDEF_TEST(RefCnt, reporter) { 71a02bc1519cf49afa31fb38bed097dd5014880d04bungeman@google.com test_refCnt(reporter); 72a02bc1519cf49afa31fb38bed097dd5014880d04bungeman@google.com test_weakRefCnt(reporter); 73a02bc1519cf49afa31fb38bed097dd5014880d04bungeman@google.com} 74bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed 75bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed/////////////////////////////////////////////////////////////////////////////////////////////////// 76bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed 77bb7b043b2db64197d2f6a1edaf3562a50c77afb1reedstatic int gRefCounter; 78bb7b043b2db64197d2f6a1edaf3562a50c77afb1reedstatic int gUnrefCounter; 79bb7b043b2db64197d2f6a1edaf3562a50c77afb1reedstatic int gNewCounter; 80bb7b043b2db64197d2f6a1edaf3562a50c77afb1reedstatic int gDeleteCounter; 81bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed 82bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed#define check(reporter, ref, unref, make, kill) \ 83bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed REPORTER_ASSERT(reporter, gRefCounter == ref); \ 84bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed REPORTER_ASSERT(reporter, gUnrefCounter == unref); \ 85bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed REPORTER_ASSERT(reporter, gNewCounter == make); \ 86bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed REPORTER_ASSERT(reporter, gDeleteCounter == kill); 87bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed 88bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed 89bb7b043b2db64197d2f6a1edaf3562a50c77afb1reedclass Effect { 90bb7b043b2db64197d2f6a1edaf3562a50c77afb1reedpublic: 91bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed Effect() : fRefCnt(1) { 92bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed gNewCounter += 1; 93bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed } 9471aca549914c868d50cd51ddff3fb7a5bfe250cdmtklein virtual ~Effect() {} 95bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed 96bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed int fRefCnt; 97bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed 98bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed void ref() { 99bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed gRefCounter += 1; 100bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed fRefCnt += 1; 101bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed } 102bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed void unref() { 103bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed gUnrefCounter += 1; 104bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed 105bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed SkASSERT(fRefCnt > 0); 106bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed if (0 == --fRefCnt) { 107bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed gDeleteCounter += 1; 108bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed delete this; 109bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed } 110bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed } 111bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed 112bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed int* method() const { return new int; } 113bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed}; 114bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed 115bb7b043b2db64197d2f6a1edaf3562a50c77afb1reedstatic sk_sp<Effect> Create() { 116217c0b3f137d824413e806759bc25378abbe8c18halcanary return sk_make_sp<Effect>(); 117bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed} 118bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed 119bb7b043b2db64197d2f6a1edaf3562a50c77afb1reedclass Paint { 120bb7b043b2db64197d2f6a1edaf3562a50c77afb1reedpublic: 121bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed sk_sp<Effect> fEffect; 122bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed 123bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed const sk_sp<Effect>& get() const { return fEffect; } 124bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed 125bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed void set(sk_sp<Effect> value) { 126bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed fEffect = std::move(value); 127bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed } 128bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed}; 129bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed 130cb6cb3841adec77d178c6d6ed006102077fd3c48halcanarystruct EffectImpl : public Effect { 13171aca549914c868d50cd51ddff3fb7a5bfe250cdmtklein ~EffectImpl() override {} 13271aca549914c868d50cd51ddff3fb7a5bfe250cdmtklein 133cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary static sk_sp<EffectImpl> Create() { 134cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary return sk_sp<EffectImpl>(new EffectImpl); 135cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary } 136cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary int fValue; 137cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary}; 138cb6cb3841adec77d178c6d6ed006102077fd3c48halcanarystatic sk_sp<Effect> make_effect() { 139cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary auto foo = EffectImpl::Create(); 140cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary foo->fValue = 42; 141cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary return std::move(foo); 142cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary} 143cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary 144cb6cb3841adec77d178c6d6ed006102077fd3c48halcanarystatic void reset_counters() { 145bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed gRefCounter = 0; 146bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed gUnrefCounter = 0; 147bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed gNewCounter = 0; 148bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed gDeleteCounter = 0; 149cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary} 150cb6cb3841adec77d178c6d6ed006102077fd3c48halcanaryDEF_TEST(sk_sp, reporter) { 151cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary reset_counters(); 152bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed 153bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed Paint paint; 154bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed REPORTER_ASSERT(reporter, paint.fEffect.get() == nullptr); 155bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed REPORTER_ASSERT(reporter, !paint.get()); 156bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed check(reporter, 0, 0, 0, 0); 157bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed 158bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed paint.set(Create()); 159bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed check(reporter, 0, 0, 1, 0); 160bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed REPORTER_ASSERT(reporter, paint.fEffect.get()->fRefCnt == 1); 161bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed 162beab9e7ba06ea8bd01fcbfd44f2ca2ed69c8a1d9bungeman if (paint.get()) { 163beab9e7ba06ea8bd01fcbfd44f2ca2ed69c8a1d9bungeman REPORTER_ASSERT(reporter, true); 164beab9e7ba06ea8bd01fcbfd44f2ca2ed69c8a1d9bungeman } else { 165beab9e7ba06ea8bd01fcbfd44f2ca2ed69c8a1d9bungeman REPORTER_ASSERT(reporter, false); 166beab9e7ba06ea8bd01fcbfd44f2ca2ed69c8a1d9bungeman } 167beab9e7ba06ea8bd01fcbfd44f2ca2ed69c8a1d9bungeman if (!paint.get()) { 168beab9e7ba06ea8bd01fcbfd44f2ca2ed69c8a1d9bungeman REPORTER_ASSERT(reporter, false); 169beab9e7ba06ea8bd01fcbfd44f2ca2ed69c8a1d9bungeman } else { 170beab9e7ba06ea8bd01fcbfd44f2ca2ed69c8a1d9bungeman REPORTER_ASSERT(reporter, true); 171beab9e7ba06ea8bd01fcbfd44f2ca2ed69c8a1d9bungeman } 172beab9e7ba06ea8bd01fcbfd44f2ca2ed69c8a1d9bungeman 173bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed paint.set(nullptr); 174bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed check(reporter, 0, 1, 1, 1); 175bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed 176beab9e7ba06ea8bd01fcbfd44f2ca2ed69c8a1d9bungeman if (paint.get()) { 177beab9e7ba06ea8bd01fcbfd44f2ca2ed69c8a1d9bungeman REPORTER_ASSERT(reporter, false); 178beab9e7ba06ea8bd01fcbfd44f2ca2ed69c8a1d9bungeman } else { 179beab9e7ba06ea8bd01fcbfd44f2ca2ed69c8a1d9bungeman REPORTER_ASSERT(reporter, true); 180beab9e7ba06ea8bd01fcbfd44f2ca2ed69c8a1d9bungeman } 181beab9e7ba06ea8bd01fcbfd44f2ca2ed69c8a1d9bungeman if (!paint.get()) { 182beab9e7ba06ea8bd01fcbfd44f2ca2ed69c8a1d9bungeman REPORTER_ASSERT(reporter, true); 183beab9e7ba06ea8bd01fcbfd44f2ca2ed69c8a1d9bungeman } else { 184beab9e7ba06ea8bd01fcbfd44f2ca2ed69c8a1d9bungeman REPORTER_ASSERT(reporter, false); 185beab9e7ba06ea8bd01fcbfd44f2ca2ed69c8a1d9bungeman } 186beab9e7ba06ea8bd01fcbfd44f2ca2ed69c8a1d9bungeman 187bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed auto e = Create(); 188bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed REPORTER_ASSERT(reporter, sizeof(e) == sizeof(void*)); 189bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed 190bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed check(reporter, 0, 1, 2, 1); 191bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed paint.set(e); 192bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed check(reporter, 1, 1, 2, 1); 193bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed REPORTER_ASSERT(reporter, paint.fEffect.get()->fRefCnt == 2); 194bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed 195bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed Paint paint2; 196bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed paint2.set(paint.get()); 197bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed check(reporter, 2, 1, 2, 1); 198bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed REPORTER_ASSERT(reporter, paint.fEffect.get()->fRefCnt == 3); 199bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed 200beab9e7ba06ea8bd01fcbfd44f2ca2ed69c8a1d9bungeman // Test sk_sp::operator-> 201bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed delete paint.get()->method(); 202bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed check(reporter, 2, 1, 2, 1); 203cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary 204beab9e7ba06ea8bd01fcbfd44f2ca2ed69c8a1d9bungeman // Test sk_sp::operator* 205beab9e7ba06ea8bd01fcbfd44f2ca2ed69c8a1d9bungeman delete (*paint.get()).method(); 206beab9e7ba06ea8bd01fcbfd44f2ca2ed69c8a1d9bungeman check(reporter, 2, 1, 2, 1); 207beab9e7ba06ea8bd01fcbfd44f2ca2ed69c8a1d9bungeman 208cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary paint.set(nullptr); 209cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary e = nullptr; 210cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary paint2.set(nullptr); 211cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary check(reporter, 2, 4, 2, 2); 212cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary 213cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary reset_counters(); 214cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary { 215cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary // Test convertible sk_sp assignment. 216cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary check(reporter, 0, 0, 0, 0); 217cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary sk_sp<Effect> foo(nullptr); 218cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary REPORTER_ASSERT(reporter, !foo); 219cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary foo = make_effect(); 220cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary REPORTER_ASSERT(reporter, foo); 221cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary check(reporter, 0, 0, 1, 0); 222cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary } 223cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary check(reporter, 0, 1, 1, 1); 224cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary 225cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary // Test passing convertible rvalue into funtion. 226cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary reset_counters(); 227cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary paint.set(EffectImpl::Create()); 228cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary check(reporter, 0, 0, 1, 0); 229cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary paint.set(nullptr); 230cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary check(reporter, 0, 1, 1, 1); 231cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary 232cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary reset_counters(); 233cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary auto baz = EffectImpl::Create(); 234cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary check(reporter, 0, 0, 1, 0); 235cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary paint.set(std::move(baz)); 236cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary check(reporter, 0, 0, 1, 0); 237cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary REPORTER_ASSERT(reporter, !baz); 238cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary paint.set(nullptr); 239cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary check(reporter, 0, 1, 1, 1); 240cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary 241cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary reset_counters(); 242cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary { 243cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary // test comparison operator with convertible type. 244cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary sk_sp<EffectImpl> bar1 = EffectImpl::Create(); 245cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary sk_sp<Effect> bar2(bar1); // convertible copy constructor 246cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary check(reporter, 1, 0, 1, 0); 247cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary REPORTER_ASSERT(reporter, bar1); 248cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary REPORTER_ASSERT(reporter, bar2); 249cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary REPORTER_ASSERT(reporter, bar1 == bar2); 250cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary REPORTER_ASSERT(reporter, bar2 == bar1); 251cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary REPORTER_ASSERT(reporter, !(bar1 != bar2)); 252cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary REPORTER_ASSERT(reporter, !(bar2 != bar1)); 253cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary sk_sp<Effect> bar3(nullptr); 254cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary bar3 = bar1; // convertible copy assignment 255cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary check(reporter, 2, 0, 1, 0); 256cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary 257cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary } 258cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary check(reporter, 2, 3, 1, 1); 259cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary 260cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary // test passing convertible copy into funtion. 261cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary reset_counters(); 262cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary baz = EffectImpl::Create(); 263cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary check(reporter, 0, 0, 1, 0); 264cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary paint.set(baz); 265cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary check(reporter, 1, 0, 1, 0); 266cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary baz = nullptr; 267cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary check(reporter, 1, 1, 1, 0); 268cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary paint.set(nullptr); 269cb6cb3841adec77d178c6d6ed006102077fd3c48halcanary check(reporter, 1, 2, 1, 1); 270c901c11549acd19e7fc225276f78374ac1600496bungeman 271c901c11549acd19e7fc225276f78374ac1600496bungeman { 272c901c11549acd19e7fc225276f78374ac1600496bungeman sk_sp<SkRefCnt> empty; 273c901c11549acd19e7fc225276f78374ac1600496bungeman sk_sp<SkRefCnt> notEmpty = sk_make_sp<SkRefCnt>(); 274c901c11549acd19e7fc225276f78374ac1600496bungeman REPORTER_ASSERT(reporter, empty == sk_sp<SkRefCnt>()); 275c901c11549acd19e7fc225276f78374ac1600496bungeman 276c901c11549acd19e7fc225276f78374ac1600496bungeman REPORTER_ASSERT(reporter, notEmpty != empty); 277c901c11549acd19e7fc225276f78374ac1600496bungeman REPORTER_ASSERT(reporter, empty != notEmpty); 278c901c11549acd19e7fc225276f78374ac1600496bungeman 279c901c11549acd19e7fc225276f78374ac1600496bungeman REPORTER_ASSERT(reporter, nullptr == empty); 280c901c11549acd19e7fc225276f78374ac1600496bungeman REPORTER_ASSERT(reporter, empty == nullptr); 281c901c11549acd19e7fc225276f78374ac1600496bungeman REPORTER_ASSERT(reporter, empty == empty); 282c901c11549acd19e7fc225276f78374ac1600496bungeman 283c901c11549acd19e7fc225276f78374ac1600496bungeman REPORTER_ASSERT(reporter, nullptr <= empty); 284c901c11549acd19e7fc225276f78374ac1600496bungeman REPORTER_ASSERT(reporter, empty <= nullptr); 285c901c11549acd19e7fc225276f78374ac1600496bungeman REPORTER_ASSERT(reporter, empty <= empty); 286c901c11549acd19e7fc225276f78374ac1600496bungeman 287c901c11549acd19e7fc225276f78374ac1600496bungeman REPORTER_ASSERT(reporter, nullptr >= empty); 288c901c11549acd19e7fc225276f78374ac1600496bungeman REPORTER_ASSERT(reporter, empty >= nullptr); 289c901c11549acd19e7fc225276f78374ac1600496bungeman REPORTER_ASSERT(reporter, empty >= empty); 290c901c11549acd19e7fc225276f78374ac1600496bungeman } 291c901c11549acd19e7fc225276f78374ac1600496bungeman 292c901c11549acd19e7fc225276f78374ac1600496bungeman { 293c901c11549acd19e7fc225276f78374ac1600496bungeman sk_sp<SkRefCnt> a = sk_make_sp<SkRefCnt>(); 294c901c11549acd19e7fc225276f78374ac1600496bungeman sk_sp<SkRefCnt> b = sk_make_sp<SkRefCnt>(); 295c901c11549acd19e7fc225276f78374ac1600496bungeman REPORTER_ASSERT(reporter, a != b); 296c901c11549acd19e7fc225276f78374ac1600496bungeman REPORTER_ASSERT(reporter, (a < b) != (b < a)); 297c901c11549acd19e7fc225276f78374ac1600496bungeman REPORTER_ASSERT(reporter, (b > a) != (a > b)); 298c901c11549acd19e7fc225276f78374ac1600496bungeman REPORTER_ASSERT(reporter, (a <= b) != (b <= a)); 299c901c11549acd19e7fc225276f78374ac1600496bungeman REPORTER_ASSERT(reporter, (b >= a) != (a >= b)); 300c901c11549acd19e7fc225276f78374ac1600496bungeman 301c901c11549acd19e7fc225276f78374ac1600496bungeman REPORTER_ASSERT(reporter, a == a); 302c901c11549acd19e7fc225276f78374ac1600496bungeman REPORTER_ASSERT(reporter, a <= a); 303c901c11549acd19e7fc225276f78374ac1600496bungeman REPORTER_ASSERT(reporter, a >= a); 304c901c11549acd19e7fc225276f78374ac1600496bungeman } 305c901c11549acd19e7fc225276f78374ac1600496bungeman 306c901c11549acd19e7fc225276f78374ac1600496bungeman // http://wg21.cmeerw.net/lwg/issue998 307c901c11549acd19e7fc225276f78374ac1600496bungeman { 308c901c11549acd19e7fc225276f78374ac1600496bungeman class foo : public SkRefCnt { 309c901c11549acd19e7fc225276f78374ac1600496bungeman public: 310c901c11549acd19e7fc225276f78374ac1600496bungeman foo() : bar(this) {} 311c901c11549acd19e7fc225276f78374ac1600496bungeman void reset() { bar.reset(); } 312c901c11549acd19e7fc225276f78374ac1600496bungeman private: 313c901c11549acd19e7fc225276f78374ac1600496bungeman sk_sp<foo> bar; 314c901c11549acd19e7fc225276f78374ac1600496bungeman }; 315c901c11549acd19e7fc225276f78374ac1600496bungeman // The following should properly delete the object and not cause undefined behavior. 316c901c11549acd19e7fc225276f78374ac1600496bungeman // This is an ugly example, but the same issue can arise in more subtle ways. 317c901c11549acd19e7fc225276f78374ac1600496bungeman (new foo)->reset(); 318c901c11549acd19e7fc225276f78374ac1600496bungeman } 319c901c11549acd19e7fc225276f78374ac1600496bungeman 320c901c11549acd19e7fc225276f78374ac1600496bungeman // https://crrev.com/0d4ef2583a6f19c3e61be04d36eb1a60b133832c 321c901c11549acd19e7fc225276f78374ac1600496bungeman { 322c901c11549acd19e7fc225276f78374ac1600496bungeman struct StructB; 323c901c11549acd19e7fc225276f78374ac1600496bungeman struct StructA : public SkRefCnt { 324c901c11549acd19e7fc225276f78374ac1600496bungeman sk_sp<StructB> b; 325c901c11549acd19e7fc225276f78374ac1600496bungeman }; 326c901c11549acd19e7fc225276f78374ac1600496bungeman 327c901c11549acd19e7fc225276f78374ac1600496bungeman struct StructB : public SkRefCnt { 328c901c11549acd19e7fc225276f78374ac1600496bungeman sk_sp<StructA> a; 329fc6c37b981daeece7474ce61070c707c37eefa62Mike Klein ~StructB() override {} // Some clang versions don't emit this implicitly. 330c901c11549acd19e7fc225276f78374ac1600496bungeman }; 331c901c11549acd19e7fc225276f78374ac1600496bungeman 332c901c11549acd19e7fc225276f78374ac1600496bungeman // Create a reference cycle. 333c901c11549acd19e7fc225276f78374ac1600496bungeman StructA* a = new StructA; 334c901c11549acd19e7fc225276f78374ac1600496bungeman a->b.reset(new StructB); 335c901c11549acd19e7fc225276f78374ac1600496bungeman a->b->a.reset(a); 336c901c11549acd19e7fc225276f78374ac1600496bungeman 337c901c11549acd19e7fc225276f78374ac1600496bungeman // Break the cycle by calling reset(). This will cause |a| (and hence, |a.b|) 338c901c11549acd19e7fc225276f78374ac1600496bungeman // to be deleted before the call to reset() returns. This tests that the 339c901c11549acd19e7fc225276f78374ac1600496bungeman // implementation of sk_sp::reset() doesn't access |this| after it 340c901c11549acd19e7fc225276f78374ac1600496bungeman // deletes the underlying pointer. This behaviour is consistent with the 341c901c11549acd19e7fc225276f78374ac1600496bungeman // definition of unique_ptr::reset in C++11. 342c901c11549acd19e7fc225276f78374ac1600496bungeman a->b.reset(); 343c901c11549acd19e7fc225276f78374ac1600496bungeman } 344bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed} 345bb7b043b2db64197d2f6a1edaf3562a50c77afb1reed 346ffa39e02bc34a33c23fcccd61b781b5d05a980d3halcanarynamespace { 347ffa39e02bc34a33c23fcccd61b781b5d05a980d3halcanarystruct FooAbstract : public SkRefCnt { 348ffa39e02bc34a33c23fcccd61b781b5d05a980d3halcanary virtual void f() = 0; 349ffa39e02bc34a33c23fcccd61b781b5d05a980d3halcanary}; 350ffa39e02bc34a33c23fcccd61b781b5d05a980d3halcanarystruct FooConcrete : public FooAbstract { 351ffa39e02bc34a33c23fcccd61b781b5d05a980d3halcanary void f() override {} 352ffa39e02bc34a33c23fcccd61b781b5d05a980d3halcanary}; 353ffa39e02bc34a33c23fcccd61b781b5d05a980d3halcanary} 354ffa39e02bc34a33c23fcccd61b781b5d05a980d3halcanarystatic sk_sp<FooAbstract> make_foo() { 355ffa39e02bc34a33c23fcccd61b781b5d05a980d3halcanary // can not cast FooConcrete to FooAbstract. 356ffa39e02bc34a33c23fcccd61b781b5d05a980d3halcanary // can cast FooConcrete* to FooAbstract*. 357ffa39e02bc34a33c23fcccd61b781b5d05a980d3halcanary return sk_make_sp<FooConcrete>(); 358ffa39e02bc34a33c23fcccd61b781b5d05a980d3halcanary} 359ffa39e02bc34a33c23fcccd61b781b5d05a980d3halcanaryDEF_TEST(sk_make_sp, r) { 360ffa39e02bc34a33c23fcccd61b781b5d05a980d3halcanary auto x = make_foo(); 361ffa39e02bc34a33c23fcccd61b781b5d05a980d3halcanary} 362941da9d66171bd8efd2f6c5e25ff90c8c69885c1reed 363941da9d66171bd8efd2f6c5e25ff90c8c69885c1reed// Test that reset() "adopts" ownership from the caller, even if we are given the same ptr twice 364941da9d66171bd8efd2f6c5e25ff90c8c69885c1reed// 365941da9d66171bd8efd2f6c5e25ff90c8c69885c1reedDEF_TEST(sk_sp_reset, r) { 366941da9d66171bd8efd2f6c5e25ff90c8c69885c1reed SkRefCnt* rc = new SkRefCnt; 367941da9d66171bd8efd2f6c5e25ff90c8c69885c1reed REPORTER_ASSERT(r, rc->unique()); 368941da9d66171bd8efd2f6c5e25ff90c8c69885c1reed 369941da9d66171bd8efd2f6c5e25ff90c8c69885c1reed sk_sp<SkRefCnt> sp; 370941da9d66171bd8efd2f6c5e25ff90c8c69885c1reed sp.reset(rc); 371941da9d66171bd8efd2f6c5e25ff90c8c69885c1reed // We have transfered our ownership over to sp 372941da9d66171bd8efd2f6c5e25ff90c8c69885c1reed REPORTER_ASSERT(r, rc->unique()); 373941da9d66171bd8efd2f6c5e25ff90c8c69885c1reed 374941da9d66171bd8efd2f6c5e25ff90c8c69885c1reed rc->ref(); // now "rc" is also an owner 375941da9d66171bd8efd2f6c5e25ff90c8c69885c1reed REPORTER_ASSERT(r, !rc->unique()); 376941da9d66171bd8efd2f6c5e25ff90c8c69885c1reed 377941da9d66171bd8efd2f6c5e25ff90c8c69885c1reed sp.reset(rc); // this should transfer our ownership over to sp 378941da9d66171bd8efd2f6c5e25ff90c8c69885c1reed REPORTER_ASSERT(r, rc->unique()); 379941da9d66171bd8efd2f6c5e25ff90c8c69885c1reed} 380647cc8474828202c98d540f799742e3074a2aacereed 381647cc8474828202c98d540f799742e3074a2aacereedDEF_TEST(sk_sp_ref, r) { 382647cc8474828202c98d540f799742e3074a2aacereed SkRefCnt* rc = new SkRefCnt; 383647cc8474828202c98d540f799742e3074a2aacereed REPORTER_ASSERT(r, rc->unique()); 384647cc8474828202c98d540f799742e3074a2aacereed 385647cc8474828202c98d540f799742e3074a2aacereed { 386647cc8474828202c98d540f799742e3074a2aacereed sk_sp<SkRefCnt> sp = sk_ref_sp(rc); 387647cc8474828202c98d540f799742e3074a2aacereed REPORTER_ASSERT(r, !rc->unique()); 388647cc8474828202c98d540f799742e3074a2aacereed } 389647cc8474828202c98d540f799742e3074a2aacereed 390647cc8474828202c98d540f799742e3074a2aacereed REPORTER_ASSERT(r, rc->unique()); 391647cc8474828202c98d540f799742e3074a2aacereed rc->unref(); 392647cc8474828202c98d540f799742e3074a2aacereed} 393