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