1 /* 2 * Copyright 2020 Google LLC 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "include/private/SkIDChangeListener.h" 9 10 #include "include/private/base/SkAssert.h" 11 12 #include <utility> 13 /** 14 * Used to be notified when a gen/unique ID is invalidated, typically to preemptively purge 15 * associated items from a cache that are no longer reachable. The listener can 16 * be marked for deregistration if the cached item is remove before the listener is 17 * triggered. This prevents unbounded listener growth when cache items are routinely 18 * removed before the gen ID/unique ID is invalidated. 19 */ 20 SkIDChangeListener()21SkIDChangeListener::SkIDChangeListener() : fShouldDeregister(false) {} 22 23 SkIDChangeListener::~SkIDChangeListener() = default; 24 25 using List = SkIDChangeListener::List; 26 27 List::List() = default; 28 ~List()29List::~List() { 30 // We don't need the mutex. No other thread should have this list while it's being 31 // destroyed. 32 for (auto& listener : fListeners) { 33 if (!listener->shouldDeregister()) { 34 listener->changed(); 35 } 36 } 37 } 38 add(sk_sp<SkIDChangeListener> listener)39void List::add(sk_sp<SkIDChangeListener> listener) { 40 if (!listener) { 41 return; 42 } 43 SkASSERT(!listener->shouldDeregister()); 44 45 SkAutoMutexExclusive lock(fMutex); 46 // Clean out any stale listeners before we append the new one. 47 for (int i = 0; i < fListeners.size(); ++i) { 48 if (fListeners[i]->shouldDeregister()) { 49 fListeners.removeShuffle(i--); // No need to preserve the order after i. 50 } 51 } 52 fListeners.push_back(std::move(listener)); 53 } 54 count() const55int List::count() const { 56 SkAutoMutexExclusive lock(fMutex); 57 return fListeners.size(); 58 } 59 changed()60void List::changed() { 61 SkAutoMutexExclusive lock(fMutex); 62 for (auto& listener : fListeners) { 63 if (!listener->shouldDeregister()) { 64 listener->changed(); 65 } 66 } 67 fListeners.clear(); 68 } 69 reset()70void List::reset() { 71 SkAutoMutexExclusive lock(fMutex); 72 fListeners.clear(); 73 } 74