image/src/DiscardTracker.h

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:e5c0d1be4425
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
4 * You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 #ifndef mozilla_imagelib_DiscardTracker_h_
7 #define mozilla_imagelib_DiscardTracker_h_
8
9 #include "mozilla/Atomics.h"
10 #include "mozilla/LinkedList.h"
11 #include "mozilla/Mutex.h"
12 #include "mozilla/TimeStamp.h"
13 #include "prlock.h"
14 #include "nsThreadUtils.h"
15 #include "nsAutoPtr.h"
16
17 class nsITimer;
18
19 namespace mozilla {
20 namespace image {
21
22 class RasterImage;
23
24 /**
25 * This static class maintains a linked list of RasterImage objects which are
26 * eligible for discarding.
27 *
28 * When Reset() is called, the node is removed from its position in the list
29 * (if it was there before) and appended to the beginnings of the list.
30 *
31 * Periodically (on a timer and when we notice that we're using more memory
32 * than we'd like for decoded images), we go through the list and discard
33 * decoded data from images at the end of the list.
34 */
35 class DiscardTracker
36 {
37 public:
38 /**
39 * The DiscardTracker keeps a linked list of Node objects. Each object
40 * points to a RasterImage and contains a timestamp indicating when the
41 * node was inserted into the tracker.
42 *
43 * This structure is embedded within each RasterImage object, and we do
44 * |mDiscardTrackerNode.img = this| on RasterImage construction. Thus, a
45 * RasterImage must always call DiscardTracker::Remove() in its destructor
46 * to avoid having the tracker point to bogus memory.
47 */
48 struct Node : public LinkedListElement<Node>
49 {
50 RasterImage *img;
51 TimeStamp timestamp;
52 };
53
54 /**
55 * Add an image to the front of the tracker's list, or move it to the front
56 * if it's already in the list. This function is main thread only.
57 */
58 static nsresult Reset(struct Node* node);
59
60 /**
61 * Remove a node from the tracker; do nothing if the node is currently
62 * untracked. This function is main thread only.
63 */
64 static void Remove(struct Node* node);
65
66 /**
67 * Initializes the discard tracker. This function is main thread only.
68 */
69 static nsresult Initialize();
70
71 /**
72 * Shut the discard tracker down. This should be called on XPCOM shutdown
73 * so we destroy the discard timer's nsITimer. This function is main thread
74 * only.
75 */
76 static void Shutdown();
77
78 /**
79 * Discard the decoded image data for all images tracked by the discard
80 * tracker. This function is main thread only.
81 */
82 static void DiscardAll();
83
84 /**
85 * Inform the discard tracker that we are going to allocate some memory
86 * for a decoded image. We use this to determine when we've allocated
87 * too much memory and should discard some images. This function can be
88 * called from any thread and is thread-safe. If this function succeeds, the
89 * caller is now responsible for ensuring that InformDeallocation is called.
90 */
91 static bool TryAllocation(uint64_t aBytes);
92
93 /**
94 * Inform the discard tracker that we've deallocated some memory for a
95 * decoded image. This function can be called from any thread and is
96 * thread-safe.
97 */
98 static void InformDeallocation(uint64_t aBytes);
99
100 private:
101 /**
102 * This is called when the discard timer fires; it calls into DiscardNow().
103 */
104 friend void DiscardTimeoutChangedCallback(const char* aPref, void *aClosure);
105
106 /**
107 * When run, this runnable sets sDiscardRunnablePending to false and calls
108 * DiscardNow().
109 */
110 class DiscardRunnable : public nsRunnable
111 {
112 NS_IMETHOD Run();
113 };
114
115 static void ReloadTimeout();
116 static nsresult EnableTimer();
117 static void DisableTimer();
118 static void MaybeDiscardSoon();
119 static void TimerCallback(nsITimer *aTimer, void *aClosure);
120 static void DiscardNow();
121
122 static LinkedList<Node> sDiscardableImages;
123 static nsCOMPtr<nsITimer> sTimer;
124 static bool sInitialized;
125 static bool sTimerOn;
126 static mozilla::Atomic<bool> sDiscardRunnablePending;
127 static uint64_t sCurrentDecodedImageBytes;
128 static uint32_t sMinDiscardTimeoutMs;
129 static uint32_t sMaxDecodedImageKB;
130 static uint32_t sHardLimitDecodedImageKB;
131 // Lock for safegarding the 64-bit sCurrentDecodedImageBytes
132 static PRLock *sAllocationLock;
133 static mozilla::Mutex* sNodeListMutex;
134 static Atomic<bool> sShutdown;
135 };
136
137 } // namespace image
138 } // namespace mozilla
139
140 #endif /* mozilla_imagelib_DiscardTracker_h_ */

mercurial