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 #ifndef SkIDChangeListener_DEFINED 9 #define SkIDChangeListener_DEFINED 10 11 #include "include/core/SkRefCnt.h" 12 #include "include/private/SkMutex.h" 13 #include "include/private/SkTDArray.h" 14 15 #include <atomic> 16 17 /** 18 * Used to be notified when a gen/unique ID is invalidated, typically to preemptively purge 19 * associated items from a cache that are no longer reachable. The listener can 20 * be marked for deregistration if the cached item is remove before the listener is 21 * triggered. This prevents unbounded listener growth when cache items are routinely 22 * removed before the gen ID/unique ID is invalidated. 23 */ 24 class SkIDChangeListener : public SkRefCnt { 25 public: 26 SkIDChangeListener(); 27 28 ~SkIDChangeListener() override; 29 30 virtual void changed() = 0; 31 32 /** 33 * Mark the listener is no longer needed. It should be removed and changed() should not be 34 * called. 35 */ markShouldDeregister()36 void markShouldDeregister() { fShouldDeregister.store(true, std::memory_order_relaxed); } 37 38 /** Indicates whether markShouldDeregister was called. */ shouldDeregister()39 bool shouldDeregister() { return fShouldDeregister.load(std::memory_order_acquire); } 40 41 /** Manages a list of SkIDChangeListeners. */ 42 class List { 43 public: 44 List(); 45 46 ~List(); 47 48 /** 49 * Add a new listener to the list. It must not already be deregistered. Also clears out 50 * previously deregistered listeners. 51 */ 52 void add(sk_sp<SkIDChangeListener> listener) SK_EXCLUDES(fMutex); 53 54 /** 55 * The number of registered listeners (including deregisterd listeners that are yet-to-be 56 * removed. 57 */ 58 int count() const SK_EXCLUDES(fMutex); 59 60 /** Calls changed() on all listeners that haven't been deregistered and resets the list. */ 61 void changed() SK_EXCLUDES(fMutex); 62 63 /** Resets without calling changed() on the listeners. */ 64 void reset() SK_EXCLUDES(fMutex); 65 66 private: 67 mutable SkMutex fMutex; 68 SkTDArray<SkIDChangeListener*> fListeners SK_GUARDED_BY(fMutex); // pointers are reffed 69 }; 70 71 private: 72 std::atomic<bool> fShouldDeregister; 73 }; 74 75 #endif 76