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