Bug 1824856 - migrate android build-bundle tasks from firefox-android. r=bhearsum...
[gecko.git] / dom / media / CallbackThreadRegistry.cpp
blob84ef7b7cb46fa2481fd7c74173e1ff8992b4af29
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"
9 #include "nsThreadUtils.h"
11 namespace mozilla {
12 struct CallbackThreadRegistrySingleton {
13 CallbackThreadRegistrySingleton()
14 : mRegistry(MakeUnique<CallbackThreadRegistry>()) {
15 NS_DispatchToMainThread(
16 NS_NewRunnableFunction(__func__, [registry = &mRegistry] {
17 const auto phase = ShutdownPhase::XPCOMShutdownFinal;
18 MOZ_DIAGNOSTIC_ASSERT(!PastShutdownPhase(phase));
19 ClearOnShutdown(registry, phase);
20 }));
23 UniquePtr<CallbackThreadRegistry> mRegistry;
26 CallbackThreadRegistry::CallbackThreadRegistry()
27 : mThreadIds("CallbackThreadRegistry::mThreadIds") {}
29 /* static */
30 CallbackThreadRegistry* CallbackThreadRegistry::Get() {
31 static CallbackThreadRegistrySingleton sSingleton;
32 return sSingleton.mRegistry.get();
35 static bool CanLeak() {
36 #ifdef NS_BUILD_REFCNT_LOGGING
37 static const bool logging =
38 getenv("XPCOM_MEM_LEAK_LOG") || getenv("XPCOM_MEM_BLOAT_LOG") ||
39 getenv("XPCOM_MEM_REFCNT_LOG") || getenv("XPCOM_MEM_ALLOC_LOG") ||
40 getenv("XPCOM_MEM_COMPTR_LOG");
41 return logging;
42 #else
43 return false;
44 #endif
47 void CallbackThreadRegistry::Register(ProfilerThreadId aThreadId,
48 const char* aName) {
49 if (!aThreadId.IsSpecified()) {
50 // profiler_current_thread_id is unspecified on unsupported platforms.
51 return;
54 if (CanLeak()) {
55 NS_WARNING(
56 "Not registering callback thread due to refcount logging; it may show "
57 "up as a leak of the TLS-backed nsThread wrapper if the thread "
58 "outlives xpcom shutdown.");
59 return;
62 auto threadIds = mThreadIds.Lock();
63 for (uint32_t i = 0; i < threadIds->Length(); i++) {
64 if ((*threadIds)[i].mId == aThreadId) {
65 (*threadIds)[i].mUserCount++;
66 return;
69 ThreadUserCount tuc;
70 tuc.mId = aThreadId;
71 tuc.mUserCount = 1;
72 threadIds->AppendElement(tuc);
73 PROFILER_REGISTER_THREAD(aName);
76 void CallbackThreadRegistry::Unregister(ProfilerThreadId aThreadId) {
77 if (!aThreadId.IsSpecified()) {
78 // profiler_current_thread_id is unspedified on unsupported platforms.
79 return;
82 if (CanLeak()) {
83 return;
86 auto threadIds = mThreadIds.Lock();
87 for (uint32_t i = 0; i < threadIds->Length(); i++) {
88 if ((*threadIds)[i].mId == aThreadId) {
89 MOZ_ASSERT((*threadIds)[i].mUserCount > 0);
90 (*threadIds)[i].mUserCount--;
92 if ((*threadIds)[i].mUserCount == 0) {
93 PROFILER_UNREGISTER_THREAD();
94 threadIds->RemoveElementAt(i);
96 return;
99 MOZ_ASSERT_UNREACHABLE("Current thread was not registered");
102 } // namespace mozilla