• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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