Bug 1358583 - Handle NS_DispatchToMainThread failures gracefully. r?njn
MozReview-Commit-ID: GP1yC1CL9GA
--- a/tools/profiler/gecko/ThreadResponsiveness.cpp
+++ b/tools/profiler/gecko/ThreadResponsiveness.cpp
@@ -16,27 +16,45 @@ using mozilla::TimeStamp;
class CheckResponsivenessTask : public mozilla::Runnable,
public nsITimerCallback {
public:
CheckResponsivenessTask()
: mLastTracerTime(TimeStamp::Now())
, mMonitor("CheckResponsivenessTask")
, mTimer(nullptr)
+ , mHasEverBeenSuccessfullyDispatched(false)
, mStop(false)
{
}
protected:
~CheckResponsivenessTask()
{
}
public:
+ // Must be called from the same thread every time. Call that the "update"
+ // thread, because it's the thread that ThreadResponsiveness::Update() is
+ // called on. In reality it's the profiler's sampler thread.
+ void DoFirstDispatchIfNeeded()
+ {
+ if (mHasEverBeenSuccessfullyDispatched) {
+ return;
+ }
+
+ // Dispatching can fail during early startup, particularly when
+ // MOZ_PROFILER_STARTUP is used.
+ nsresult rv = NS_DispatchToMainThread(this);
+ if (NS_SUCCEEDED(rv)) {
+ mHasEverBeenSuccessfullyDispatched = true;
+ }
+ }
+
// Can only run on the main thread.
NS_IMETHOD Run() override
{
MonitorAutoLock mon(mMonitor);
if (mStop)
return NS_OK;
// This is raced on because we might pause the thread here
@@ -69,39 +87,34 @@ public:
}
NS_DECL_ISUPPORTS_INHERITED
private:
TimeStamp mLastTracerTime;
Monitor mMonitor;
nsCOMPtr<nsITimer> mTimer;
+ bool mHasEverBeenSuccessfullyDispatched; // only accessed on the "update" thread
bool mStop;
};
NS_IMPL_ISUPPORTS_INHERITED(CheckResponsivenessTask, mozilla::Runnable,
nsITimerCallback)
ThreadResponsiveness::ThreadResponsiveness()
- : mActiveTracerEvent(nullptr)
+ : mActiveTracerEvent(new CheckResponsivenessTask())
{
MOZ_COUNT_CTOR(ThreadResponsiveness);
}
ThreadResponsiveness::~ThreadResponsiveness()
{
MOZ_COUNT_DTOR(ThreadResponsiveness);
- if (mActiveTracerEvent) {
- mActiveTracerEvent->Terminate();
- }
+ mActiveTracerEvent->Terminate();
}
void
ThreadResponsiveness::Update()
{
- if (!mActiveTracerEvent) {
- mActiveTracerEvent = new CheckResponsivenessTask();
- NS_DispatchToMainThread(mActiveTracerEvent);
- }
-
+ mActiveTracerEvent->DoFirstDispatchIfNeeded();
mLastTracerTime = mActiveTracerEvent->GetLastTracerTime();
}