no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / dom / media / CallbackThreadRegistry.cpp
blobf4d2af5bd1326f5e188ef8a0235e3b4e72a817d4
1 /* -*- Mode: C++; tab-width: 2; 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 file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "CallbackThreadRegistry.h"
8 #include "mozilla/ClearOnShutdown.h"
10 namespace mozilla {
11 struct CallbackThreadRegistrySingleton {
12 CallbackThreadRegistrySingleton()
13 : mRegistry(MakeUnique<CallbackThreadRegistry>()) {
14 NS_DispatchToMainThread(
15 NS_NewRunnableFunction(__func__, [registry = &mRegistry] {
16 const auto phase = ShutdownPhase::XPCOMShutdownFinal;
17 MOZ_DIAGNOSTIC_ASSERT(!PastShutdownPhase(phase));
18 ClearOnShutdown(registry, phase);
19 }));
22 UniquePtr<CallbackThreadRegistry> mRegistry;
25 CallbackThreadRegistry::CallbackThreadRegistry()
26 : mThreadIds("CallbackThreadRegistry::mThreadIds") {}
28 /* static */
29 CallbackThreadRegistry* CallbackThreadRegistry::Get() {
30 static CallbackThreadRegistrySingleton sSingleton;
31 return sSingleton.mRegistry.get();
34 static bool CanLeak() {
35 #ifdef NS_BUILD_REFCNT_LOGGING
36 static const bool logging =
37 getenv("XPCOM_MEM_LEAK_LOG") || getenv("XPCOM_MEM_BLOAT_LOG") ||
38 getenv("XPCOM_MEM_REFCNT_LOG") || getenv("XPCOM_MEM_ALLOC_LOG") ||
39 getenv("XPCOM_MEM_COMPTR_LOG");
40 return logging;
41 #else
42 return false;
43 #endif
46 void CallbackThreadRegistry::Register(ProfilerThreadId aThreadId,
47 const char* aName) {
48 if (!aThreadId.IsSpecified()) {
49 // profiler_current_thread_id is unspecified on unsupported platforms.
50 return;
53 if (CanLeak()) {
54 NS_WARNING(
55 "Not registering callback thread due to refcount logging; it may show "
56 "up as a leak of the TLS-backed nsThread wrapper if the thread "
57 "outlives xpcom shutdown.");
58 return;
61 auto threadIds = mThreadIds.Lock();
62 for (uint32_t i = 0; i < threadIds->Length(); i++) {
63 if ((*threadIds)[i].mId == aThreadId) {
64 (*threadIds)[i].mUserCount++;
65 return;
68 ThreadUserCount tuc;
69 tuc.mId = aThreadId;
70 tuc.mUserCount = 1;
71 threadIds->AppendElement(tuc);
72 PROFILER_REGISTER_THREAD(aName);
75 void CallbackThreadRegistry::Unregister(ProfilerThreadId aThreadId) {
76 if (!aThreadId.IsSpecified()) {
77 // profiler_current_thread_id is unspedified on unsupported platforms.
78 return;
81 if (CanLeak()) {
82 return;
85 auto threadIds = mThreadIds.Lock();
86 for (uint32_t i = 0; i < threadIds->Length(); i++) {
87 if ((*threadIds)[i].mId == aThreadId) {
88 MOZ_ASSERT((*threadIds)[i].mUserCount > 0);
89 (*threadIds)[i].mUserCount--;
91 if ((*threadIds)[i].mUserCount == 0) {
92 PROFILER_UNREGISTER_THREAD();
93 threadIds->RemoveElementAt(i);
95 return;
98 MOZ_ASSERT_UNREACHABLE("Current thread was not registered");
101 } // namespace mozilla