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/. */
7 #ifndef NSCATEGORYMANAGER_H
8 #define NSCATEGORYMANAGER_H
11 #include "nsClassHashtable.h"
12 #include "nsICategoryManager.h"
13 #include "nsIMemoryReporter.h"
14 #include "mozilla/ArenaAllocator.h"
15 #include "mozilla/MemoryReporting.h"
16 #include "mozilla/Mutex.h"
17 #include "mozilla/Attributes.h"
19 class nsIMemoryReporter
;
21 typedef mozilla::ArenaAllocator
<1024 * 8, 8> CategoryAllocator
;
23 /* 16d222a6-1dd2-11b2-b693-f38b02c021b2 */
24 #define NS_CATEGORYMANAGER_CID \
26 0x16d222a6, 0x1dd2, 0x11b2, { \
27 0xb6, 0x93, 0xf3, 0x8b, 0x02, 0xc0, 0x21, 0xb2 \
32 * a "leaf-node", managed by the nsCategoryNode hashtable.
34 * we need to keep a "persistent value" (which will be written to the registry)
35 * and a non-persistent value (for the current runtime): these are usually
36 * the same, except when aPersist==false. The strings are permanently arena-
37 * allocated, and will never go away.
39 class CategoryLeaf
: public nsDepCharHashKey
{
41 explicit CategoryLeaf(const char* aKey
)
42 : nsDepCharHashKey(aKey
), value(nullptr) {}
47 * CategoryNode keeps a hashtable of its entries.
48 * the CategoryNode itself is permanently allocated in
53 nsresult
GetLeaf(const nsACString
& aEntryName
, nsACString
& aResult
);
55 nsresult
AddLeaf(const nsACString
& aEntryName
, const nsACString
& aValue
,
56 bool aReplace
, nsACString
& aResult
,
57 CategoryAllocator
* aArena
);
59 void DeleteLeaf(const nsACString
& aEntryName
);
62 mozilla::MutexAutoLock
lock(mLock
);
67 mozilla::MutexAutoLock
lock(mLock
);
68 uint32_t tCount
= mTable
.Count();
72 nsresult
Enumerate(nsISimpleEnumerator
** aResult
);
74 // CategoryNode is arena-allocated, with the strings
75 static CategoryNode
* Create(CategoryAllocator
* aArena
);
77 void operator delete(void*) {}
79 size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf
);
82 CategoryNode() : mLock("CategoryLeaf") {}
84 void* operator new(size_t aSize
, CategoryAllocator
* aArena
);
86 nsTHashtable
<CategoryLeaf
> mTable
MOZ_GUARDED_BY(mLock
);
91 * The main implementation of nsICategoryManager.
93 * This implementation is thread-safe.
95 class nsCategoryManager final
: public nsICategoryManager
,
96 public nsIMemoryReporter
{
99 NS_DECL_NSICATEGORYMANAGER
100 NS_DECL_NSIMEMORYREPORTER
103 * Suppress or unsuppress notifications of category changes to the
104 * observer service. This is to be used by nsComponentManagerImpl
105 * on startup while reading the stored category list.
107 nsresult
SuppressNotifications(bool aSuppress
);
109 void AddCategoryEntry(const nsACString
& aCategory
, const nsACString
& aKey
,
110 const nsACString
& aValue
, bool aReplace
,
111 nsACString
& aOldValue
);
113 void AddCategoryEntry(const nsACString
& aCategory
, const nsACString
& aKey
,
114 const nsACString
& aValue
, bool aReplace
= true) {
116 return AddCategoryEntry(aCategory
, aKey
, aValue
, aReplace
, oldValue
);
119 static nsresult
Create(REFNSIID aIID
, void** aResult
);
120 void InitMemoryReporter();
122 static nsCategoryManager
* GetSingleton();
123 static void Destroy();
126 static nsCategoryManager
* gCategoryManager
;
129 ~nsCategoryManager();
131 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf
);
133 CategoryNode
* get_category(const nsACString
& aName
) MOZ_REQUIRES(mLock
);
134 void NotifyObservers(
136 const nsACString
& aCategoryName
, // must be a static string
137 const nsACString
& aEntryName
);
139 CategoryAllocator mArena
; // Mainthread only
140 nsClassHashtable
<nsDepCharHashKey
, CategoryNode
> mTable
MOZ_GUARDED_BY(mLock
);
141 mozilla::Mutex mLock
;
142 bool mSuppressNotifications
; // Mainthread only