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