Bug 1362953 - Refactored lock-protected TelemetryHistogram code to be more similar to other sections of code. r?Dexter draft
authorMichael Calabrese <mcalabrese85@gmail.com>
Wed, 16 May 2018 19:08:14 -0400
changeset 796073 040a731f0f98ebf2ee7c7dfec600a566f882e7ef
parent 795657 3c9d69736f4a421218e5eb01b6571d535d38318a
push id110156
push userbmo:mcalabrese85@gmail.com
push dateWed, 16 May 2018 23:10:11 +0000
reviewersDexter
bugs1362953
milestone62.0a1
Bug 1362953 - Refactored lock-protected TelemetryHistogram code to be more similar to other sections of code. r?Dexter MozReview-Commit-ID: EjznJVDhOPn
toolkit/components/telemetry/TelemetryHistogram.cpp
--- a/toolkit/components/telemetry/TelemetryHistogram.cpp
+++ b/toolkit/components/telemetry/TelemetryHistogram.cpp
@@ -258,42 +258,45 @@ const HistogramID kRecordingInitiallyDis
 namespace {
 
 size_t internal_KeyedHistogramStorageIndex(HistogramID aHistogramId,
                                            ProcessID aProcessId)
 {
   return aHistogramId * size_t(ProcessID::Count) + size_t(aProcessId);
 }
 
-size_t internal_HistogramStorageIndex(HistogramID aHistogramId,
+size_t internal_HistogramStorageIndex(const StaticMutexAutoLock& lock,
+                                      HistogramID aHistogramId,
                                       ProcessID aProcessId)
 {
   static_assert(
     HistogramCount <
       std::numeric_limits<size_t>::max() / size_t(ProcessID::Count),
         "Too many histograms and processes to store in a 1D array.");
 
   return aHistogramId * size_t(ProcessID::Count) + size_t(aProcessId);
 }
 
-Histogram* internal_GetHistogramFromStorage(HistogramID aHistogramId,
+Histogram* internal_GetHistogramFromStorage(const StaticMutexAutoLock& lock,
+                                            HistogramID aHistogramId,
                                             ProcessID aProcessId)
 {
-  size_t index = internal_HistogramStorageIndex(aHistogramId, aProcessId);
+  size_t index = internal_HistogramStorageIndex(lock, aHistogramId, aProcessId);
   return gHistogramStorage[index];
 }
 
-void internal_SetHistogramInStorage(HistogramID aHistogramId,
+void internal_SetHistogramInStorage(const StaticMutexAutoLock& lock,
+                                    HistogramID aHistogramId,
                                     ProcessID aProcessId,
                                     Histogram* aHistogram)
 {
   MOZ_ASSERT(XRE_IsParentProcess(),
     "Histograms are stored only in the parent process.");
 
-  size_t index = internal_HistogramStorageIndex(aHistogramId, aProcessId);
+  size_t index = internal_HistogramStorageIndex(lock, aHistogramId, aProcessId);
   MOZ_ASSERT(!gHistogramStorage[index],
     "Mustn't overwrite storage without clearing it first.");
   gHistogramStorage[index] = aHistogram;
 }
 
 KeyedHistogram* internal_GetKeyedHistogramFromStorage(HistogramID aHistogramId,
                                                       ProcessID aProcessId)
 {
@@ -322,32 +325,33 @@ bool
 internal_IsHistogramEnumId(HistogramID aID)
 {
   static_assert(((HistogramID)-1 > 0), "ID should be unsigned.");
   return aID < HistogramCount;
 }
 
 // Look up a plain histogram by id.
 Histogram*
-internal_GetHistogramById(HistogramID histogramId, ProcessID processId, bool instantiate = true)
+internal_GetHistogramById(const StaticMutexAutoLock& lock, HistogramID histogramId, ProcessID processId, bool instantiate = true)
 {
   MOZ_ASSERT(internal_IsHistogramEnumId(histogramId));
   MOZ_ASSERT(!gHistogramInfos[histogramId].keyed);
   MOZ_ASSERT(processId < ProcessID::Count);
 
-  Histogram* h = internal_GetHistogramFromStorage(histogramId, processId);
+  Histogram* h = internal_GetHistogramFromStorage(lock, histogramId, processId);
+
   if (h || !instantiate) {
     return h;
   }
 
   const HistogramInfo& info = gHistogramInfos[histogramId];
   const int bucketsOffset = gHistogramBucketLowerBoundIndex[histogramId];
   h = internal_CreateHistogramInstance(info, bucketsOffset);
   MOZ_ASSERT(h);
-  internal_SetHistogramInStorage(histogramId, processId, h);
+  internal_SetHistogramInStorage(lock, histogramId, processId, h);
   return h;
 }
 
 // Look up a keyed histogram by id.
 KeyedHistogram*
 internal_GetKeyedHistogramById(HistogramID histogramId, ProcessID processId,
                                bool instantiate = true)
 {
@@ -365,31 +369,31 @@ internal_GetKeyedHistogramById(Histogram
   kh = new KeyedHistogram(histogramId, info);
   internal_SetKeyedHistogramInStorage(histogramId, processId, kh);
 
   return kh;
 }
 
 // Look up a histogram id from a histogram name.
 nsresult
-internal_GetHistogramIdByName(const nsACString& name, HistogramID* id)
+internal_GetHistogramIdByName(const StaticMutexAutoLock& lock, const nsACString& name, HistogramID* id)
 {
   const bool found = gNameToHistogramIDMap.Get(name, id);
   if (!found) {
     return NS_ERROR_ILLEGAL_VALUE;
   }
 
   return NS_OK;
 }
 
 // Clear a histogram from storage.
 void
-internal_ClearHistogramById(HistogramID histogramId, ProcessID processId)
+internal_ClearHistogramById(const StaticMutexAutoLock& lock, HistogramID histogramId, ProcessID processId)
 {
-  size_t index = internal_HistogramStorageIndex(histogramId, processId);
+  size_t index = internal_HistogramStorageIndex(lock, histogramId, processId);
   if (gHistogramStorage[index] == gExpiredHistogram) {
     // We keep gExpiredHistogram until TelemetryHistogram::DeInitializeGlobalState
     return;
   }
   delete gHistogramStorage[index];
   gHistogramStorage[index] = nullptr;
 }
 
@@ -409,29 +413,29 @@ internal_CanRecordBase() {
 
 bool
 internal_CanRecordExtended() {
   return gCanRecordExtended;
 }
 
 // Note: this is completely unrelated to mozilla::IsEmpty.
 bool
-internal_IsEmpty(const Histogram *h)
+internal_IsEmpty(const StaticMutexAutoLock& lock, const Histogram *h)
 {
   return h->is_empty();
 }
 
 bool
-internal_IsExpired(Histogram* h)
+internal_IsExpired(const StaticMutexAutoLock& lock, Histogram* h)
 {
   return h == gExpiredHistogram;
 }
 
 void
-internal_SetHistogramRecordingEnabled(HistogramID id, bool aEnabled)
+internal_SetHistogramRecordingEnabled(const StaticMutexAutoLock& lock, HistogramID id, bool aEnabled)
 {
   MOZ_ASSERT(internal_IsHistogramEnumId(id));
   gHistogramRecordingDisabled[id] = !aEnabled;
 }
 
 bool
 internal_IsRecordingEnabled(HistogramID id)
 {
@@ -590,17 +594,18 @@ internal_CreateHistogramInstance(const H
   if (isExpired) {
     gExpiredHistogram = h;
   }
 
   return h;
 }
 
 nsresult
-internal_HistogramAdd(Histogram& histogram,
+internal_HistogramAdd(const StaticMutexAutoLock& lock,
+                      Histogram& histogram,
                       const HistogramID id,
                       uint32_t value,
                       ProcessID aProcessType)
 {
   // Check if we are allowed to record the data.
   bool canRecordDataset = CanRecordDataset(gHistogramInfos[id].dataset,
                                            internal_CanRecordBase(),
                                            internal_CanRecordExtended());
@@ -730,24 +735,24 @@ internal_ReflectHistogramAndSamples(JSCo
       return NS_ERROR_FAILURE;
     }
   }
 
   return NS_OK;
 }
 
 bool
-internal_ShouldReflectHistogram(Histogram* h, HistogramID id)
+internal_ShouldReflectHistogram(const StaticMutexAutoLock& lock, Histogram* h, HistogramID id)
 {
   // Only flag histograms are serialized when they are empty.
   // This has historical reasons, changing this will require downstream changes.
   // The cheaper path here is to just deprecate flag histograms in favor
   // of scalars.
   uint32_t type = gHistogramInfos[id].histogramType;
-  if (internal_IsEmpty(h) && type != nsITelemetry::HISTOGRAM_FLAG) {
+  if (internal_IsEmpty(lock, h) && type != nsITelemetry::HISTOGRAM_FLAG) {
     return false;
   }
 
   return true;
 }
 
 } // namespace
 
@@ -977,101 +982,102 @@ KeyedHistogram::GetSnapshot(const Static
 ////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////
 //
 // PRIVATE: thread-unsafe helpers for the external interface
 
 namespace {
 
 bool
-internal_RemoteAccumulate(HistogramID aId, uint32_t aSample)
+internal_RemoteAccumulate(const StaticMutexAutoLock& lock, HistogramID aId, uint32_t aSample)
 {
   if (XRE_IsParentProcess()) {
     return false;
   }
 
   if (!internal_IsRecordingEnabled(aId)) {
     return true;
   }
 
   TelemetryIPCAccumulator::AccumulateChildHistogram(aId, aSample);
   return true;
 }
 
 bool
-internal_RemoteAccumulate(HistogramID aId,
+internal_RemoteAccumulate(const StaticMutexAutoLock& lock,
+                          HistogramID aId,
                           const nsCString& aKey, uint32_t aSample)
 {
   if (XRE_IsParentProcess()) {
     return false;
   }
 
   if (!internal_IsRecordingEnabled(aId)) {
     return true;
   }
 
   TelemetryIPCAccumulator::AccumulateChildKeyedHistogram(aId, aKey, aSample);
   return true;
 }
 
-void internal_Accumulate(HistogramID aId, uint32_t aSample)
+void internal_Accumulate(const StaticMutexAutoLock& lock, HistogramID aId, uint32_t aSample)
 {
   if (!internal_CanRecordBase() ||
-      internal_RemoteAccumulate(aId, aSample)) {
+      internal_RemoteAccumulate(lock, aId, aSample)) {
     return;
   }
 
-  Histogram *h = internal_GetHistogramById(aId, ProcessID::Parent);
+  Histogram *h = internal_GetHistogramById(lock, aId, ProcessID::Parent);
   MOZ_ASSERT(h);
-  internal_HistogramAdd(*h, aId, aSample, ProcessID::Parent);
+  internal_HistogramAdd(lock, *h, aId, aSample, ProcessID::Parent);
 }
 
 void
-internal_Accumulate(HistogramID aId,
+internal_Accumulate(const StaticMutexAutoLock& lock, HistogramID aId,
                     const nsCString& aKey, uint32_t aSample)
 {
   if (!gInitDone || !internal_CanRecordBase() ||
-      internal_RemoteAccumulate(aId, aKey, aSample)) {
+      internal_RemoteAccumulate(lock, aId, aKey, aSample)) {
     return;
   }
 
   KeyedHistogram* keyed = internal_GetKeyedHistogramById(aId, ProcessID::Parent);
   MOZ_ASSERT(keyed);
   keyed->Add(aKey, aSample, ProcessID::Parent);
 }
 
 void
-internal_AccumulateChild(ProcessID aProcessType, HistogramID aId, uint32_t aSample)
+internal_AccumulateChild(const StaticMutexAutoLock& lock, ProcessID aProcessType, HistogramID aId, uint32_t aSample)
 {
   if (!internal_CanRecordBase()) {
     return;
   }
 
-  if (Histogram* h = internal_GetHistogramById(aId, aProcessType)) {
-    internal_HistogramAdd(*h, aId, aSample, aProcessType);
+  if (Histogram* h = internal_GetHistogramById(lock, aId, aProcessType)) {
+    internal_HistogramAdd(lock, *h, aId, aSample, aProcessType);
   } else {
     NS_WARNING("Failed GetHistogramById for CHILD");
   }
 }
 
 void
-internal_AccumulateChildKeyed(ProcessID aProcessType, HistogramID aId,
+internal_AccumulateChildKeyed(const StaticMutexAutoLock& lock, ProcessID aProcessType, HistogramID aId,
                               const nsCString& aKey, uint32_t aSample)
 {
   if (!gInitDone || !internal_CanRecordBase()) {
     return;
   }
 
   KeyedHistogram* keyed = internal_GetKeyedHistogramById(aId, aProcessType);
   MOZ_ASSERT(keyed);
   keyed->Add(aKey, aSample, aProcessType);
 }
 
 void
-internal_ClearHistogram(HistogramID id)
+internal_ClearHistogram(const StaticMutexAutoLock& lock, HistogramID id)
 {
   MOZ_ASSERT(XRE_IsParentProcess());
   if (!XRE_IsParentProcess()) {
     return;
   }
 
   // Handle keyed histograms.
   if (gHistogramInfos[id].keyed) {
@@ -1080,21 +1086,22 @@ internal_ClearHistogram(HistogramID id)
       if (kh) {
         kh->Clear();
       }
     }
   }
 
   // Now reset the histograms instances for all processes.
   for (uint32_t process = 0; process < static_cast<uint32_t>(ProcessID::Count); ++process) {
-    internal_ClearHistogramById(id, static_cast<ProcessID>(process));
+      internal_ClearHistogramById(lock, id, static_cast<ProcessID>(process));
+    }
   }
 }
 
-} // namespace
+// namespace
 
 
 ////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////
 //
 // PRIVATE: JSHistogram_* functions
 
 // NOTE: the functions in this section:
@@ -1280,17 +1287,17 @@ internal_JSHistogram_Add(JSContext *cx, 
     // Either GetValueArray or CoerceValue utility function will have printed a meaningful
     // error message, so we simply return true
     return true;
   }
 
   {
     StaticMutexAutoLock locker(gTelemetryHistogramMutex);
     for (uint32_t aValue: values) {
-      internal_Accumulate(id, aValue);
+      internal_Accumulate(locker, id, aValue);
     }
   }
   return true;
 }
 
 bool
 internal_JSHistogram_Snapshot(JSContext *cx, unsigned argc, JS::Value *vp)
 {
@@ -1310,17 +1317,17 @@ internal_JSHistogram_Snapshot(JSContext 
   HistogramSnapshotData dataSnapshot;
   {
     StaticMutexAutoLock locker(gTelemetryHistogramMutex);
     MOZ_ASSERT(internal_IsHistogramEnumId(id));
 
     // This is not good standard behavior given that we have histogram instances
     // covering multiple processes.
     // However, changing this requires some broader changes to callers.
-    Histogram* h = internal_GetHistogramById(id, ProcessID::Parent);
+    Histogram* h = internal_GetHistogramById(locker, id, ProcessID::Parent);
     // Take a snapshot of the data here, protected by the lock, and then,
     // outside of the lock protection, mirror it to a JS structure
     if (NS_FAILED(internal_GetHistogramAndSamples(locker, h, dataSnapshot))) {
       return false;
     }
   }
 
   JS::Rooted<JSObject*> snapshot(cx, JS_NewPlainObject(cx));
@@ -1358,17 +1365,17 @@ internal_JSHistogram_Clear(JSContext *cx
   // rather report failures using the console.
   args.rval().setUndefined();
 
   HistogramID id = data->histogramId;
   {
     StaticMutexAutoLock locker(gTelemetryHistogramMutex);
 
     MOZ_ASSERT(internal_IsHistogramEnumId(id));
-    internal_ClearHistogram(id);
+    internal_ClearHistogram(locker, id);
   }
 
   return true;
 }
 
 // NOTE: Runs without protection from |gTelemetryHistogramMutex|.
 // See comment at the top of this section.
 nsresult
@@ -1592,17 +1599,17 @@ internal_JSKeyedHistogram_Add(JSContext 
     // Either GetValueArray or CoerceValue utility function will have printed a meaningful
     // error message so we simple return true
     return true;
   }
 
   {
     StaticMutexAutoLock locker(gTelemetryHistogramMutex);
     for (uint32_t aValue: values) {
-      internal_Accumulate(id, NS_ConvertUTF16toUTF8(key), aValue);
+      internal_Accumulate(locker, id, NS_ConvertUTF16toUTF8(key), aValue);
     }
   }
   return true;
 }
 
 bool
 internal_JSKeyedHistogram_Keys(JSContext *cx, unsigned argc, JS::Value *vp)
 {
@@ -1868,21 +1875,21 @@ TelemetryHistogram::InitHistogramRecordi
 {
   StaticMutexAutoLock locker(gTelemetryHistogramMutex);
   auto processType = XRE_GetProcessType();
   for (size_t i = 0; i < HistogramCount; ++i) {
     const HistogramInfo& h = gHistogramInfos[i];
     mozilla::Telemetry::HistogramID id = mozilla::Telemetry::HistogramID(i);
     bool canRecordInProcess = CanRecordInProcess(h.record_in_processes, processType);
     bool canRecordProduct = CanRecordProduct(h.products);
-    internal_SetHistogramRecordingEnabled(id, canRecordInProcess && canRecordProduct);
+    internal_SetHistogramRecordingEnabled(locker, id, canRecordInProcess && canRecordProduct);
   }
 
   for (auto recordingInitiallyDisabledID : kRecordingInitiallyDisabledIDs) {
-    internal_SetHistogramRecordingEnabled(recordingInitiallyDisabledID,
+    internal_SetHistogramRecordingEnabled(locker, recordingInitiallyDisabledID,
                                           false);
   }
 }
 
 void
 TelemetryHistogram::SetHistogramRecordingEnabled(HistogramID aID,
                                                  bool aEnabled)
 {
@@ -1898,64 +1905,64 @@ TelemetryHistogram::SetHistogramRecordin
   }
 
   if (!CanRecordProduct(h.products)) {
     // Don't permit products-disabled recording to be re-enabled.
     return;
   }
 
   StaticMutexAutoLock locker(gTelemetryHistogramMutex);
-  internal_SetHistogramRecordingEnabled(aID, aEnabled);
+  internal_SetHistogramRecordingEnabled(locker, aID, aEnabled);
 }
 
 
 nsresult
 TelemetryHistogram::SetHistogramRecordingEnabled(const nsACString& name,
                                                  bool aEnabled)
 {
   StaticMutexAutoLock locker(gTelemetryHistogramMutex);
   HistogramID id;
-  if (NS_FAILED(internal_GetHistogramIdByName(name, &id))) {
+  if (NS_FAILED(internal_GetHistogramIdByName(locker, name, &id))) {
     return NS_ERROR_FAILURE;
   }
 
   const HistogramInfo& hi = gHistogramInfos[id];
   if (CanRecordInProcess(hi.record_in_processes, XRE_GetProcessType())) {
-    internal_SetHistogramRecordingEnabled(id, aEnabled);
+    internal_SetHistogramRecordingEnabled(locker, id, aEnabled);
   }
   return NS_OK;
 }
 
 
 void
 TelemetryHistogram::Accumulate(HistogramID aID,
                                uint32_t aSample)
 {
   if (NS_WARN_IF(!internal_IsHistogramEnumId(aID))) {
     MOZ_ASSERT_UNREACHABLE("Histogram usage requires valid ids.");
     return;
   }
 
   StaticMutexAutoLock locker(gTelemetryHistogramMutex);
-  internal_Accumulate(aID, aSample);
+  internal_Accumulate(locker, aID, aSample);
 }
 
 void
 TelemetryHistogram::Accumulate(HistogramID aID, const nsTArray<uint32_t>& aSamples)
 {
   if (NS_WARN_IF(!internal_IsHistogramEnumId(aID))) {
     MOZ_ASSERT_UNREACHABLE("Histogram usage requires valid ids.");
     return;
   }
 
   MOZ_ASSERT(!gHistogramInfos[aID].keyed, "Cannot accumulate into a keyed histogram. No key given.");
 
   StaticMutexAutoLock locker(gTelemetryHistogramMutex);
   for(uint32_t sample: aSamples){
-    internal_Accumulate(aID, sample);
+    internal_Accumulate(locker, aID, sample);
   }
 }
 
 void
 TelemetryHistogram::Accumulate(HistogramID aID,
                                const nsCString& aKey, uint32_t aSample)
 {
   if (NS_WARN_IF(!internal_IsHistogramEnumId(aID))) {
@@ -1971,17 +1978,17 @@ TelemetryHistogram::Accumulate(Histogram
     LogToBrowserConsole(nsIScriptError::errorFlag, NS_ConvertUTF8toUTF16(msg));
     TelemetryScalar::Add(
       mozilla::Telemetry::ScalarID::TELEMETRY_ACCUMULATE_UNKNOWN_HISTOGRAM_KEYS,
       NS_ConvertASCIItoUTF16(gHistogramInfos[aID].name()), 1);
     return;
   }
 
   StaticMutexAutoLock locker(gTelemetryHistogramMutex);
-  internal_Accumulate(aID, aKey, aSample);
+  internal_Accumulate(locker, aID, aKey, aSample);
 }
 
 void
 TelemetryHistogram::Accumulate(HistogramID aID, const nsCString& aKey,
                               const nsTArray<uint32_t>& aSamples)
 {
   if (NS_WARN_IF(!internal_IsHistogramEnumId(aID))) {
     MOZ_ASSERT_UNREACHABLE("Histogram usage requires valid ids");
@@ -2000,52 +2007,52 @@ TelemetryHistogram::Accumulate(Histogram
     TelemetryScalar::Add(
       mozilla::Telemetry::ScalarID::TELEMETRY_ACCUMULATE_UNKNOWN_HISTOGRAM_KEYS,
       NS_ConvertASCIItoUTF16(gHistogramInfos[aID].name()), 1);
     return;
   }
 
   StaticMutexAutoLock locker(gTelemetryHistogramMutex);
   for(uint32_t sample: aSamples){
-    internal_Accumulate(aID, aKey, sample);
+    internal_Accumulate(locker, aID, aKey, sample);
   }
 }
 
 void
 TelemetryHistogram::Accumulate(const char* name, uint32_t sample)
 {
   StaticMutexAutoLock locker(gTelemetryHistogramMutex);
   if (!internal_CanRecordBase()) {
     return;
   }
   HistogramID id;
-  nsresult rv = internal_GetHistogramIdByName(nsDependentCString(name), &id);
+  nsresult rv = internal_GetHistogramIdByName(locker, nsDependentCString(name), &id);
   if (NS_FAILED(rv)) {
     return;
   }
-  internal_Accumulate(id, sample);
+  internal_Accumulate(locker, id, sample);
 }
 
 void
 TelemetryHistogram::Accumulate(const char* name,
                                const nsCString& key, uint32_t sample)
 {
   bool keyNotAllowed = false;
 
   {
     StaticMutexAutoLock locker(gTelemetryHistogramMutex);
     if (!internal_CanRecordBase()) {
       return;
     }
     HistogramID id;
-    nsresult rv = internal_GetHistogramIdByName(nsDependentCString(name), &id);
+    nsresult rv = internal_GetHistogramIdByName(locker, nsDependentCString(name), &id);
     if (NS_SUCCEEDED(rv)) {
       // Check if we're allowed to record in the provided key, for this histogram.
       if (gHistogramInfos[id].allows_key(key)) {
-        internal_Accumulate(id, key, sample);
+        internal_Accumulate(locker, id, key, sample);
         return;
       }
       // We're holding |gTelemetryHistogramMutex|, so we can't print a message
       // here.
       keyNotAllowed = true;
     }
    }
 
@@ -2070,17 +2077,17 @@ TelemetryHistogram::AccumulateCategorica
   StaticMutexAutoLock locker(gTelemetryHistogramMutex);
   if (!internal_CanRecordBase()) {
     return;
   }
   uint32_t labelId = 0;
   if (NS_FAILED(gHistogramInfos[aId].label_id(label.get(), &labelId))) {
     return;
   }
-  internal_Accumulate(aId, labelId);
+  internal_Accumulate(locker, aId, labelId);
 }
 
 void
 TelemetryHistogram::AccumulateCategorical(HistogramID aId, const nsTArray<nsCString>& aLabels)
 {
   if (NS_WARN_IF(!internal_IsHistogramEnumId(aId))) {
     MOZ_ASSERT_UNREACHABLE("Histogram usage requires valid ids.");
     return;
@@ -2102,17 +2109,17 @@ TelemetryHistogram::AccumulateCategorica
       return;
     }
     intSamples.AppendElement(labelId);
   }
 
   StaticMutexAutoLock locker(gTelemetryHistogramMutex);
 
   for (uint32_t sample: intSamples){
-    internal_Accumulate(aId, sample);
+    internal_Accumulate(locker, aId, sample);
   }
 }
 
 void
 TelemetryHistogram::AccumulateChild(ProcessID aProcessType,
                                     const nsTArray<HistogramAccumulation>& aAccumulations)
 {
   MOZ_ASSERT(XRE_IsParentProcess());
@@ -2121,17 +2128,17 @@ TelemetryHistogram::AccumulateChild(Proc
   if (!internal_CanRecordBase()) {
     return;
   }
   for (uint32_t i = 0; i < aAccumulations.Length(); ++i) {
     if (NS_WARN_IF(!internal_IsHistogramEnumId(aAccumulations[i].mId))) {
       MOZ_ASSERT_UNREACHABLE("Histogram usage requires valid ids.");
       continue;
     }
-    internal_AccumulateChild(aProcessType, aAccumulations[i].mId, aAccumulations[i].mSample);
+    internal_AccumulateChild(locker, aProcessType, aAccumulations[i].mId, aAccumulations[i].mSample);
   }
 }
 
 void
 TelemetryHistogram::AccumulateChildKeyed(ProcessID aProcessType,
                                          const nsTArray<KeyedHistogramAccumulation>& aAccumulations)
 {
   MOZ_ASSERT(XRE_IsParentProcess());
@@ -2139,31 +2146,32 @@ TelemetryHistogram::AccumulateChildKeyed
   if (!internal_CanRecordBase()) {
     return;
   }
   for (uint32_t i = 0; i < aAccumulations.Length(); ++i) {
     if (NS_WARN_IF(!internal_IsHistogramEnumId(aAccumulations[i].mId))) {
       MOZ_ASSERT_UNREACHABLE("Histogram usage requires valid ids.");
       continue;
     }
-    internal_AccumulateChildKeyed(aProcessType,
+    internal_AccumulateChildKeyed(locker,
+                                  aProcessType,
                                   aAccumulations[i].mId,
                                   aAccumulations[i].mKey,
                                   aAccumulations[i].mSample);
   }
 }
 
 nsresult
 TelemetryHistogram::GetHistogramById(const nsACString &name, JSContext *cx,
                                      JS::MutableHandle<JS::Value> ret)
 {
   HistogramID id;
   {
     StaticMutexAutoLock locker(gTelemetryHistogramMutex);
-    nsresult rv = internal_GetHistogramIdByName(name, &id);
+    nsresult rv = internal_GetHistogramIdByName(locker, name, &id);
     if (NS_FAILED(rv)) {
       return NS_ERROR_FAILURE;
     }
 
     if (gHistogramInfos[id].keyed) {
       return NS_ERROR_FAILURE;
     }
   }
@@ -2174,17 +2182,17 @@ TelemetryHistogram::GetHistogramById(con
 nsresult
 TelemetryHistogram::GetKeyedHistogramById(const nsACString &name,
                                           JSContext *cx,
                                           JS::MutableHandle<JS::Value> ret)
 {
   HistogramID id;
   {
     StaticMutexAutoLock locker(gTelemetryHistogramMutex);
-    nsresult rv = internal_GetHistogramIdByName(name, &id);
+    nsresult rv = internal_GetHistogramIdByName(locker, name, &id);
     if (NS_FAILED(rv)) {
       return NS_ERROR_FAILURE;
     }
 
     if (!gHistogramInfos[id].keyed) {
       return NS_ERROR_FAILURE;
     }
   }
@@ -2256,19 +2264,20 @@ TelemetryHistogram::CreateHistogramSnaps
         }
 
         if (!IsInDataset(info.dataset, aDataset)) {
           continue;
         }
 
         bool shouldInstantiate =
           info.histogramType == nsITelemetry::HISTOGRAM_FLAG;
-        Histogram* h = internal_GetHistogramById(id, ProcessID(process),
+        Histogram* h = internal_GetHistogramById(locker, id,
+                                                 ProcessID(process),
                                                  shouldInstantiate);
-        if (!h || internal_IsExpired(h) || !internal_ShouldReflectHistogram(h, id)) {
+        if (!h || internal_IsExpired(locker, h) || !internal_ShouldReflectHistogram(locker, h, id)) {
           continue;
         }
 
         HistogramSnapshotData snapshotData;
         if (NS_FAILED(internal_GetHistogramAndSamples(locker, h, snapshotData))) {
           continue;
         }