Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
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
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef nsRefPtrHashtable_h__
7 #define nsRefPtrHashtable_h__
9 #include "nsBaseHashtable.h"
10 #include "nsHashKeys.h"
11 #include "nsAutoPtr.h"
13 /**
14 * templated hashtable class maps keys to reference pointers.
15 * See nsBaseHashtable for complete declaration.
16 * @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h
17 * for a complete specification.
18 * @param RefPtr the reference-type being wrapped
19 * @see nsDataHashtable, nsClassHashtable
20 */
21 template<class KeyClass, class RefPtr>
22 class nsRefPtrHashtable :
23 public nsBaseHashtable< KeyClass, nsRefPtr<RefPtr> , RefPtr* >
24 {
25 public:
26 typedef typename KeyClass::KeyType KeyType;
27 typedef RefPtr* UserDataType;
28 typedef nsBaseHashtable< KeyClass, nsRefPtr<RefPtr> , RefPtr* > base_type;
30 nsRefPtrHashtable()
31 {
32 }
33 explicit nsRefPtrHashtable(uint32_t aInitSize)
34 : nsBaseHashtable<KeyClass,nsRefPtr<RefPtr>,RefPtr*>(aInitSize)
35 {
36 }
38 /**
39 * @copydoc nsBaseHashtable::Get
40 * @param pData This is an XPCOM getter, so pData is already_addrefed.
41 * If the key doesn't exist, pData will be set to nullptr.
42 */
43 bool Get(KeyType aKey, UserDataType* pData) const;
45 /**
46 * Gets a weak reference to the hashtable entry.
47 * @param aFound If not nullptr, will be set to true if the entry is found,
48 * to false otherwise.
49 * @return The entry, or nullptr if not found. Do not release this pointer!
50 */
51 RefPtr* GetWeak(KeyType aKey, bool* aFound = nullptr) const;
53 // Overload Remove, rather than overriding it.
54 using base_type::Remove;
56 /**
57 * Remove the data for the associated key, swapping the current value into
58 * pData, thereby avoiding calls to AddRef and Release.
59 * @param aKey the key to remove from the hashtable
60 * @param pData This is an XPCOM getter, so pData is already_addrefed.
61 * If the key doesn't exist, pData will be set to nullptr. Must be non-null.
62 */
63 bool Remove(KeyType aKey, UserDataType* pData);
64 };
66 template <typename K, typename T>
67 inline void
68 ImplCycleCollectionUnlink(nsRefPtrHashtable<K, T>& aField)
69 {
70 aField.Clear();
71 }
73 template <typename K, typename T>
74 inline void
75 ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
76 nsRefPtrHashtable<K, T>& aField,
77 const char* aName,
78 uint32_t aFlags = 0)
79 {
80 nsBaseHashtableCCTraversalData userData(aCallback, aName, aFlags);
82 aField.EnumerateRead(ImplCycleCollectionTraverse_EnumFunc<typename K::KeyType,T*>,
83 &userData);
84 }
86 //
87 // nsRefPtrHashtable definitions
88 //
90 template<class KeyClass, class RefPtr>
91 bool
92 nsRefPtrHashtable<KeyClass,RefPtr>::Get
93 (KeyType aKey, UserDataType* pRefPtr) const
94 {
95 typename base_type::EntryType* ent = this->GetEntry(aKey);
97 if (ent) {
98 if (pRefPtr) {
99 *pRefPtr = ent->mData;
101 NS_IF_ADDREF(*pRefPtr);
102 }
104 return true;
105 }
107 // if the key doesn't exist, set *pRefPtr to null
108 // so that it is a valid XPCOM getter
109 if (pRefPtr) {
110 *pRefPtr = nullptr;
111 }
113 return false;
114 }
116 template<class KeyClass, class RefPtr>
117 RefPtr*
118 nsRefPtrHashtable<KeyClass,RefPtr>::GetWeak
119 (KeyType aKey, bool* aFound) const
120 {
121 typename base_type::EntryType* ent = this->GetEntry(aKey);
123 if (ent) {
124 if (aFound) {
125 *aFound = true;
126 }
128 return ent->mData;
129 }
131 // Key does not exist, return nullptr and set aFound to false
132 if (aFound) {
133 *aFound = false;
134 }
136 return nullptr;
137 }
139 template<class KeyClass, class RefPtr>
140 bool
141 nsRefPtrHashtable<KeyClass,RefPtr>::Remove(KeyType aKey,
142 UserDataType* pRefPtr)
143 {
144 MOZ_ASSERT(pRefPtr);
145 typename base_type::EntryType* ent = this->GetEntry(aKey);
147 if (ent) {
148 ent->mData.forget(pRefPtr);
149 this->Remove(aKey);
150 return true;
151 }
153 // If the key doesn't exist, set *pRefPtr to null
154 // so that it is a valid XPCOM getter.
155 *pRefPtr = nullptr;
156 return false;
157 }
159 #endif // nsRefPtrHashtable_h__