xpcom/glue/nsRefPtrHashtable.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

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.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #ifndef nsRefPtrHashtable_h__
michael@0 7 #define nsRefPtrHashtable_h__
michael@0 8
michael@0 9 #include "nsBaseHashtable.h"
michael@0 10 #include "nsHashKeys.h"
michael@0 11 #include "nsAutoPtr.h"
michael@0 12
michael@0 13 /**
michael@0 14 * templated hashtable class maps keys to reference pointers.
michael@0 15 * See nsBaseHashtable for complete declaration.
michael@0 16 * @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h
michael@0 17 * for a complete specification.
michael@0 18 * @param RefPtr the reference-type being wrapped
michael@0 19 * @see nsDataHashtable, nsClassHashtable
michael@0 20 */
michael@0 21 template<class KeyClass, class RefPtr>
michael@0 22 class nsRefPtrHashtable :
michael@0 23 public nsBaseHashtable< KeyClass, nsRefPtr<RefPtr> , RefPtr* >
michael@0 24 {
michael@0 25 public:
michael@0 26 typedef typename KeyClass::KeyType KeyType;
michael@0 27 typedef RefPtr* UserDataType;
michael@0 28 typedef nsBaseHashtable< KeyClass, nsRefPtr<RefPtr> , RefPtr* > base_type;
michael@0 29
michael@0 30 nsRefPtrHashtable()
michael@0 31 {
michael@0 32 }
michael@0 33 explicit nsRefPtrHashtable(uint32_t aInitSize)
michael@0 34 : nsBaseHashtable<KeyClass,nsRefPtr<RefPtr>,RefPtr*>(aInitSize)
michael@0 35 {
michael@0 36 }
michael@0 37
michael@0 38 /**
michael@0 39 * @copydoc nsBaseHashtable::Get
michael@0 40 * @param pData This is an XPCOM getter, so pData is already_addrefed.
michael@0 41 * If the key doesn't exist, pData will be set to nullptr.
michael@0 42 */
michael@0 43 bool Get(KeyType aKey, UserDataType* pData) const;
michael@0 44
michael@0 45 /**
michael@0 46 * Gets a weak reference to the hashtable entry.
michael@0 47 * @param aFound If not nullptr, will be set to true if the entry is found,
michael@0 48 * to false otherwise.
michael@0 49 * @return The entry, or nullptr if not found. Do not release this pointer!
michael@0 50 */
michael@0 51 RefPtr* GetWeak(KeyType aKey, bool* aFound = nullptr) const;
michael@0 52
michael@0 53 // Overload Remove, rather than overriding it.
michael@0 54 using base_type::Remove;
michael@0 55
michael@0 56 /**
michael@0 57 * Remove the data for the associated key, swapping the current value into
michael@0 58 * pData, thereby avoiding calls to AddRef and Release.
michael@0 59 * @param aKey the key to remove from the hashtable
michael@0 60 * @param pData This is an XPCOM getter, so pData is already_addrefed.
michael@0 61 * If the key doesn't exist, pData will be set to nullptr. Must be non-null.
michael@0 62 */
michael@0 63 bool Remove(KeyType aKey, UserDataType* pData);
michael@0 64 };
michael@0 65
michael@0 66 template <typename K, typename T>
michael@0 67 inline void
michael@0 68 ImplCycleCollectionUnlink(nsRefPtrHashtable<K, T>& aField)
michael@0 69 {
michael@0 70 aField.Clear();
michael@0 71 }
michael@0 72
michael@0 73 template <typename K, typename T>
michael@0 74 inline void
michael@0 75 ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
michael@0 76 nsRefPtrHashtable<K, T>& aField,
michael@0 77 const char* aName,
michael@0 78 uint32_t aFlags = 0)
michael@0 79 {
michael@0 80 nsBaseHashtableCCTraversalData userData(aCallback, aName, aFlags);
michael@0 81
michael@0 82 aField.EnumerateRead(ImplCycleCollectionTraverse_EnumFunc<typename K::KeyType,T*>,
michael@0 83 &userData);
michael@0 84 }
michael@0 85
michael@0 86 //
michael@0 87 // nsRefPtrHashtable definitions
michael@0 88 //
michael@0 89
michael@0 90 template<class KeyClass, class RefPtr>
michael@0 91 bool
michael@0 92 nsRefPtrHashtable<KeyClass,RefPtr>::Get
michael@0 93 (KeyType aKey, UserDataType* pRefPtr) const
michael@0 94 {
michael@0 95 typename base_type::EntryType* ent = this->GetEntry(aKey);
michael@0 96
michael@0 97 if (ent) {
michael@0 98 if (pRefPtr) {
michael@0 99 *pRefPtr = ent->mData;
michael@0 100
michael@0 101 NS_IF_ADDREF(*pRefPtr);
michael@0 102 }
michael@0 103
michael@0 104 return true;
michael@0 105 }
michael@0 106
michael@0 107 // if the key doesn't exist, set *pRefPtr to null
michael@0 108 // so that it is a valid XPCOM getter
michael@0 109 if (pRefPtr) {
michael@0 110 *pRefPtr = nullptr;
michael@0 111 }
michael@0 112
michael@0 113 return false;
michael@0 114 }
michael@0 115
michael@0 116 template<class KeyClass, class RefPtr>
michael@0 117 RefPtr*
michael@0 118 nsRefPtrHashtable<KeyClass,RefPtr>::GetWeak
michael@0 119 (KeyType aKey, bool* aFound) const
michael@0 120 {
michael@0 121 typename base_type::EntryType* ent = this->GetEntry(aKey);
michael@0 122
michael@0 123 if (ent) {
michael@0 124 if (aFound) {
michael@0 125 *aFound = true;
michael@0 126 }
michael@0 127
michael@0 128 return ent->mData;
michael@0 129 }
michael@0 130
michael@0 131 // Key does not exist, return nullptr and set aFound to false
michael@0 132 if (aFound) {
michael@0 133 *aFound = false;
michael@0 134 }
michael@0 135
michael@0 136 return nullptr;
michael@0 137 }
michael@0 138
michael@0 139 template<class KeyClass, class RefPtr>
michael@0 140 bool
michael@0 141 nsRefPtrHashtable<KeyClass,RefPtr>::Remove(KeyType aKey,
michael@0 142 UserDataType* pRefPtr)
michael@0 143 {
michael@0 144 MOZ_ASSERT(pRefPtr);
michael@0 145 typename base_type::EntryType* ent = this->GetEntry(aKey);
michael@0 146
michael@0 147 if (ent) {
michael@0 148 ent->mData.forget(pRefPtr);
michael@0 149 this->Remove(aKey);
michael@0 150 return true;
michael@0 151 }
michael@0 152
michael@0 153 // If the key doesn't exist, set *pRefPtr to null
michael@0 154 // so that it is a valid XPCOM getter.
michael@0 155 *pRefPtr = nullptr;
michael@0 156 return false;
michael@0 157 }
michael@0 158
michael@0 159 #endif // nsRefPtrHashtable_h__

mercurial