Bug 1046292 - Add a max-wait timeout to TaskThrottler to robustify against it getting stuck. r=botond

This commit is contained in:
Kartikaya Gupta 2014-07-31 09:04:34 -04:00
parent aca1e4c415
commit eea46e2278
4 changed files with 26 additions and 15 deletions

View File

@ -443,11 +443,6 @@ TabChildBase::UpdateFrameHandler(const FrameMetrics& aFrameMetrics)
return true;
}
}
// We've recieved a message that is out of date and we want to ignore.
// However we can't reply without painting so we reply by painting the
// exact same thing as we did before.
mLastRootMetrics = ProcessUpdateFrame(mLastRootMetrics);
return true;
}

View File

@ -709,7 +709,7 @@ AsyncPanZoomController::AsyncPanZoomController(uint64_t aLayersId,
GeckoContentController* aGeckoContentController,
GestureBehavior aGestures)
: mLayersId(aLayersId),
mPaintThrottler(GetFrameTime()),
mPaintThrottler(GetFrameTime(), TimeDuration::FromMilliseconds(500)),
mGeckoContentController(aGeckoContentController),
mRefPtrMonitor("RefPtrMonitor"),
mSharingFrameMetricsAcrossProcesses(false),

View File

@ -9,10 +9,11 @@
namespace mozilla {
namespace layers {
TaskThrottler::TaskThrottler(const TimeStamp& aTimeStamp)
TaskThrottler::TaskThrottler(const TimeStamp& aTimeStamp, const TimeDuration& aMaxWait)
: mOutstanding(false)
, mQueuedTask(nullptr)
, mStartTime(aTimeStamp)
, mMaxWait(aMaxWait)
, mMean(1)
{ }
@ -25,13 +26,19 @@ TaskThrottler::PostTask(const tracked_objects::Location& aLocation,
if (mOutstanding) {
if (mQueuedTask) {
mQueuedTask->Cancel();
mQueuedTask = nullptr;
}
mQueuedTask = Move(aTask);
} else {
mStartTime = aTimeStamp;
aTask->Run();
mOutstanding = true;
if (TimeSinceLastRequest(aTimeStamp) < mMaxWait) {
mQueuedTask = Move(aTask);
return;
}
// we've been waiting for more than the max-wait limit, so just fall through
// and send the new task already.
}
mStartTime = aTimeStamp;
aTask->Run();
mOutstanding = true;
}
void

View File

@ -26,10 +26,16 @@ namespace layers {
* you're sending an async message and waiting for a reply. You need to call
* PostTask to queue a task and TaskComplete when you get a response.
*
* The call to TaskComplete will run the recent task posted since the last
* The call to TaskComplete will run the most recent task posted since the last
* request was sent, if any. This means that at any time there can be at most 1
* outstanding request being processed and at most 1 queued behind it.
*
* However, to guard against task runs that error out and fail to call TaskComplete,
* the TaskThrottler also has a max-wait timeout. If the caller requests a new
* task be posted, and it has been greater than the max-wait timeout since the
* last one was sent, then we send the new one regardless of whether or not the
* last one was marked as completed.
*
* This is used in the context of repainting a scrollable region. While another
* process is painting you might get several updates from the UI thread but when
* the paint is complete you want to send the most recent.
@ -37,9 +43,11 @@ namespace layers {
class TaskThrottler {
public:
TaskThrottler(const TimeStamp& aTimeStamp);
TaskThrottler(const TimeStamp& aTimeStamp, const TimeDuration& aMaxWait);
/** Post a task to be run as soon as there are no outstanding tasks.
/** Post a task to be run as soon as there are no outstanding tasks, or
* post it immediately if it has been more than the max-wait time since
* the last task was posted.
*
* @param aLocation Use the macro FROM_HERE
* @param aTask Ownership of this object is transferred to TaskThrottler
@ -92,6 +100,7 @@ private:
bool mOutstanding;
UniquePtr<CancelableTask> mQueuedTask;
TimeStamp mStartTime;
TimeDuration mMaxWait;
RollingMean<TimeDuration, TimeDuration> mMean;
};