Bug 1244897 - Use TimerlineConsumers in PopProfileTimelineMarkers to ensure that all methods acquire TimelineConsumers Mutex. r=vporof
authorHiroyuki Ikezoe <hiikezoe@mozilla-japan.org>
Tue, 01 Mar 2016 19:54:47 +0900
changeset 286404 c100740d395b89ead4a252c739c022911c0f34b3
parent 286403 0a2dadeedd4f221d859bee69db3f83a48454c45c
child 286405 bfc0b3c2844d43022d4623aa0080e63383099216
push id30045
push usercbook@mozilla.com
push dateWed, 02 Mar 2016 14:54:36 +0000
treeherdermozilla-central@bdde3fedb45b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvporof
bugs1244897
milestone47.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1244897 - Use TimerlineConsumers in PopProfileTimelineMarkers to ensure that all methods acquire TimelineConsumers Mutex. r=vporof MozReview-Commit-ID: 5VzLfT5SUjI
docshell/base/nsDocShell.cpp
docshell/base/nsDocShell.h
docshell/base/timeline/ObservedDocShell.cpp
docshell/base/timeline/TimelineConsumers.cpp
docshell/base/timeline/TimelineConsumers.h
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -2876,22 +2876,25 @@ nsDocShell::GetRecordProfileTimelineMark
   return NS_OK;
 }
 
 nsresult
 nsDocShell::PopProfileTimelineMarkers(
     JSContext* aCx,
     JS::MutableHandle<JS::Value> aOut)
 {
+  RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
+  if (!timelines) {
+    return NS_OK;
+  }
+
   nsTArray<dom::ProfileTimelineMarker> store;
   SequenceRooter<dom::ProfileTimelineMarker> rooter(aCx, &store);
 
-  if (mObserved) {
-    mObserved->PopMarkers(aCx, store);
-  }
+  timelines->PopMarkers(this, aCx, store);
 
   if (!ToJSValue(aCx, store, aOut)) {
     JS_ClearPendingException(aCx);
     return NS_ERROR_UNEXPECTED;
   }
 
   return NS_OK;
 }
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -289,16 +289,18 @@ private:
   friend void mozilla::TimelineConsumers::AddConsumer(nsDocShell*);
   friend void mozilla::TimelineConsumers::RemoveConsumer(nsDocShell*);
   friend void mozilla::TimelineConsumers::AddMarkerForDocShell(
     nsDocShell*, const char*, MarkerTracingType);
   friend void mozilla::TimelineConsumers::AddMarkerForDocShell(
     nsDocShell*, const char*, const TimeStamp&, MarkerTracingType);
   friend void mozilla::TimelineConsumers::AddMarkerForDocShell(
     nsDocShell*, UniquePtr<AbstractTimelineMarker>&&);
+  friend void mozilla::TimelineConsumers::PopMarkers(nsDocShell*,
+    JSContext*, nsTArray<dom::ProfileTimelineMarker>&);
 
 public:
   // Tell the favicon service that aNewURI has the same favicon as aOldURI.
   static void CopyFavicon(nsIURI* aOldURI,
                           nsIURI* aNewURI,
                           nsIPrincipal* aLoadingPrincipal,
                           bool aInPrivateBrowsing);
 
--- a/docshell/base/timeline/ObservedDocShell.cpp
+++ b/docshell/base/timeline/ObservedDocShell.cpp
@@ -40,16 +40,17 @@ ObservedDocShell::AddOTMTMarker(UniquePt
   MOZ_ASSERT(!NS_IsMainThread());
   MutexAutoLock lock(GetLock()); // for `mOffTheMainThreadTimelineMarkers`.
   mOffTheMainThreadTimelineMarkers.AppendElement(Move(aMarker));
 }
 
 void
 ObservedDocShell::ClearMarkers()
 {
+  MOZ_ASSERT(NS_IsMainThread());
   MutexAutoLock lock(GetLock()); // for `mOffTheMainThreadTimelineMarkers`.
   mTimelineMarkers.Clear();
   mOffTheMainThreadTimelineMarkers.Clear();
 }
 
 void
 ObservedDocShell::PopMarkers(JSContext* aCx,
                              nsTArray<dom::ProfileTimelineMarker>& aStore)
--- a/docshell/base/timeline/TimelineConsumers.cpp
+++ b/docshell/base/timeline/TimelineConsumers.cpp
@@ -289,9 +289,24 @@ TimelineConsumers::AddMarkerForAllObserv
     if (isMainThread) {
       storage->AddMarker(Move(clone));
     } else {
       storage->AddOTMTMarker(Move(clone));
     }
   }
 }
 
+void
+TimelineConsumers::PopMarkers(nsDocShell* aDocShell,
+                              JSContext* aCx,
+                              nsTArray<dom::ProfileTimelineMarker>& aStore)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  StaticMutexAutoLock lock(sMutex); // for `mMarkersStores`.
+
+  if (!aDocShell || !aDocShell->mObserved) {
+    return;
+  }
+
+  aDocShell->mObserved->PopMarkers(aCx, aStore);
+}
+
 } // namespace mozilla
--- a/docshell/base/timeline/TimelineConsumers.h
+++ b/docshell/base/timeline/TimelineConsumers.h
@@ -10,22 +10,27 @@
 #include "mozilla/StaticPtr.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/LinkedList.h"
 #include "mozilla/StaticMutex.h"
 #include "TimelineMarkerEnums.h" // for MarkerTracingType
 
 class nsDocShell;
 class nsIDocShell;
+struct JSContext;
 
 namespace mozilla {
 class TimeStamp;
 class MarkersStorage;
 class AbstractTimelineMarker;
 
+namespace dom {
+struct ProfileTimelineMarker;
+}
+
 class TimelineConsumers : public nsIObserver
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIOBSERVER
 
 private:
   TimelineConsumers();
@@ -99,16 +104,20 @@ public:
                                         MarkerTracingType aTracingType,
                                         MarkerStackRequest aStackRequest = MarkerStackRequest::STACK);
 
   // This method clones and registers an already instantiated marker,
   // which doesn't have to be relevant to a specific docshell.
   // May be called from any thread.
   void AddMarkerForAllObservedDocShells(UniquePtr<AbstractTimelineMarker>& aMarker);
 
+  void PopMarkers(nsDocShell* aDocShell,
+                  JSContext* aCx,
+                  nsTArray<dom::ProfileTimelineMarker>& aStore);
+
 private:
   static StaticRefPtr<TimelineConsumers> sInstance;
   static bool sInShutdown;
 
   // Counter for how many timelines are currently interested in markers,
   // and a list of the MarkersStorage interfaces representing them.
   unsigned long mActiveConsumers;
   LinkedList<MarkersStorage> mMarkersStores;