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 #include "mozilla/HangAnnotations.h"
8
9 #include <vector>
10
11 #include "MainThreadUtils.h"
12 #include "mozilla/DebugOnly.h"
13 #include "nsXULAppAPI.h"
14 #include "mozilla/BackgroundHangMonitor.h"
15
16 namespace mozilla {
17
AddAnnotation(const nsString & aName,const int32_t aData)18 void BackgroundHangAnnotations::AddAnnotation(const nsString& aName,
19 const int32_t aData) {
20 nsAutoString dataString;
21 dataString.AppendInt(aData);
22 AppendElement(HangAnnotation(aName, dataString));
23 }
24
AddAnnotation(const nsString & aName,const double aData)25 void BackgroundHangAnnotations::AddAnnotation(const nsString& aName,
26 const double aData) {
27 nsAutoString dataString;
28 dataString.AppendFloat(aData);
29 AppendElement(HangAnnotation(aName, dataString));
30 }
31
AddAnnotation(const nsString & aName,const nsString & aData)32 void BackgroundHangAnnotations::AddAnnotation(const nsString& aName,
33 const nsString& aData) {
34 AppendElement(HangAnnotation(aName, aData));
35 }
36
AddAnnotation(const nsString & aName,const nsCString & aData)37 void BackgroundHangAnnotations::AddAnnotation(const nsString& aName,
38 const nsCString& aData) {
39 NS_ConvertUTF8toUTF16 dataString(aData);
40 AppendElement(HangAnnotation(aName, dataString));
41 }
42
AddAnnotation(const nsString & aName,const bool aData)43 void BackgroundHangAnnotations::AddAnnotation(const nsString& aName,
44 const bool aData) {
45 if (aData) {
46 AppendElement(HangAnnotation(aName, u"true"_ns));
47 } else {
48 AppendElement(HangAnnotation(aName, u"false"_ns));
49 }
50 }
51
BackgroundHangAnnotators()52 BackgroundHangAnnotators::BackgroundHangAnnotators()
53 : mMutex("BackgroundHangAnnotators::mMutex") {
54 MOZ_COUNT_CTOR(BackgroundHangAnnotators);
55 }
56
~BackgroundHangAnnotators()57 BackgroundHangAnnotators::~BackgroundHangAnnotators() {
58 MOZ_ASSERT(mAnnotators.empty());
59 MOZ_COUNT_DTOR(BackgroundHangAnnotators);
60 }
61
Register(BackgroundHangAnnotator & aAnnotator)62 bool BackgroundHangAnnotators::Register(BackgroundHangAnnotator& aAnnotator) {
63 MutexAutoLock lock(mMutex);
64 auto result = mAnnotators.insert(&aAnnotator);
65 return result.second;
66 }
67
Unregister(BackgroundHangAnnotator & aAnnotator)68 bool BackgroundHangAnnotators::Unregister(BackgroundHangAnnotator& aAnnotator) {
69 MutexAutoLock lock(mMutex);
70 DebugOnly<std::set<BackgroundHangAnnotator*>::size_type> numErased;
71 numErased = mAnnotators.erase(&aAnnotator);
72 MOZ_ASSERT(numErased == 1);
73 return mAnnotators.empty();
74 }
75
GatherAnnotations()76 BackgroundHangAnnotations BackgroundHangAnnotators::GatherAnnotations() {
77 BackgroundHangAnnotations annotations;
78 { // Scope for lock
79 MutexAutoLock lock(mMutex);
80 for (std::set<BackgroundHangAnnotator*>::iterator i = mAnnotators.begin(),
81 e = mAnnotators.end();
82 i != e; ++i) {
83 (*i)->AnnotateHang(annotations);
84 }
85 }
86 return annotations;
87 }
88
89 } // namespace mozilla
90