Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 :
8 : #ifndef NSCATEGORYMANAGER_H
9 : #define NSCATEGORYMANAGER_H
10 :
11 : #include "prio.h"
12 : #include "nsClassHashtable.h"
13 : #include "nsICategoryManager.h"
14 : #include "nsIMemoryReporter.h"
15 : #include "mozilla/ArenaAllocator.h"
16 : #include "mozilla/MemoryReporting.h"
17 : #include "mozilla/Mutex.h"
18 : #include "mozilla/Attributes.h"
19 :
20 : class nsIMemoryReporter;
21 :
22 : typedef mozilla::ArenaAllocator<1024*8, 8> CategoryAllocator;
23 :
24 : /* 16d222a6-1dd2-11b2-b693-f38b02c021b2 */
25 : #define NS_CATEGORYMANAGER_CID \
26 : { 0x16d222a6, 0x1dd2, 0x11b2, \
27 : {0xb6, 0x93, 0xf3, 0x8b, 0x02, 0xc0, 0x21, 0xb2} }
28 :
29 : /**
30 : * a "leaf-node", managed by the nsCategoryNode hashtable.
31 : *
32 : * we need to keep a "persistent value" (which will be written to the registry)
33 : * and a non-persistent value (for the current runtime): these are usually
34 : * the same, except when aPersist==false. The strings are permanently arena-
35 : * allocated, and will never go away.
36 : */
37 0 : class CategoryLeaf : public nsDepCharHashKey
38 : {
39 : public:
40 442 : explicit CategoryLeaf(const char* aKey) : nsDepCharHashKey(aKey), value(nullptr) {}
41 : const char* value;
42 : };
43 :
44 :
45 : /**
46 : * CategoryNode keeps a hashtable of its entries.
47 : * the CategoryNode itself is permanently allocated in
48 : * the arena.
49 : */
50 0 : class CategoryNode
51 : {
52 : public:
53 : nsresult GetLeaf(const char* aEntryName,
54 : char** aResult);
55 :
56 : nsresult AddLeaf(const char* aEntryName,
57 : const char* aValue,
58 : bool aReplace,
59 : char** aResult,
60 : CategoryAllocator* aArena);
61 :
62 : void DeleteLeaf(const char* aEntryName);
63 :
64 0 : void Clear()
65 : {
66 0 : mozilla::MutexAutoLock lock(mLock);
67 0 : mTable.Clear();
68 0 : }
69 :
70 0 : uint32_t Count()
71 : {
72 0 : mozilla::MutexAutoLock lock(mLock);
73 0 : uint32_t tCount = mTable.Count();
74 0 : return tCount;
75 : }
76 :
77 : nsresult Enumerate(nsISimpleEnumerator** aResult);
78 :
79 : // CategoryNode is arena-allocated, with the strings
80 : static CategoryNode* Create(CategoryAllocator* aArena);
81 : ~CategoryNode();
82 0 : void operator delete(void*) {}
83 :
84 : size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf);
85 :
86 : private:
87 98 : CategoryNode() : mLock("CategoryLeaf") {}
88 :
89 : void* operator new(size_t aSize, CategoryAllocator* aArena);
90 :
91 : nsTHashtable<CategoryLeaf> mTable;
92 : mozilla::Mutex mLock;
93 : };
94 :
95 :
96 : /**
97 : * The main implementation of nsICategoryManager.
98 : *
99 : * This implementation is thread-safe.
100 : */
101 : class nsCategoryManager final
102 : : public nsICategoryManager
103 : , public nsIMemoryReporter
104 : {
105 : public:
106 : NS_DECL_ISUPPORTS
107 : NS_DECL_NSICATEGORYMANAGER
108 : NS_DECL_NSIMEMORYREPORTER
109 :
110 : /**
111 : * Suppress or unsuppress notifications of category changes to the
112 : * observer service. This is to be used by nsComponentManagerImpl
113 : * on startup while reading the stored category list.
114 : */
115 : nsresult SuppressNotifications(bool aSuppress);
116 :
117 : void AddCategoryEntry(const char* aCategory,
118 : const char* aKey,
119 : const char* aValue,
120 : bool aReplace = true,
121 : char** aOldValue = nullptr);
122 :
123 : static nsresult Create(nsISupports* aOuter, REFNSIID aIID, void** aResult);
124 : void InitMemoryReporter();
125 :
126 : static nsCategoryManager* GetSingleton();
127 : static void Destroy();
128 :
129 : private:
130 : static nsCategoryManager* gCategoryManager;
131 :
132 : nsCategoryManager();
133 : ~nsCategoryManager();
134 :
135 : size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
136 :
137 : CategoryNode* get_category(const char* aName);
138 : void NotifyObservers(const char* aTopic,
139 : const char* aCategoryName, // must be a static string
140 : const char* aEntryName);
141 :
142 : CategoryAllocator mArena;
143 : nsClassHashtable<nsDepCharHashKey, CategoryNode> mTable;
144 : mozilla::Mutex mLock;
145 : bool mSuppressNotifications;
146 : };
147 :
148 : #endif
|