Bug 1244897 - Use TimerlineConsumers in PopProfileTimelineMarkers to ensure that all methods acquire TimelineConsumers Mutex. r?vporof
MozReview-Commit-ID: 5VzLfT5SUjI
--- 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;