|
1 /* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 2; -*- */ |
|
2 /* vim: set sw=4 ts=8 et tw=80 : */ |
|
3 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 |
|
7 #ifndef mozilla_dom_TaskThrottler_h |
|
8 #define mozilla_dom_TaskThrottler_h |
|
9 |
|
10 #include <stdint.h> // for uint32_t |
|
11 #include "base/task.h" // for CancelableTask |
|
12 #include "mozilla/TimeStamp.h" // for TimeDuration, TimeStamp |
|
13 #include "mozilla/RollingMean.h" // for RollingMean |
|
14 #include "mozilla/mozalloc.h" // for operator delete |
|
15 #include "nsAutoPtr.h" // for nsAutoPtr |
|
16 #include "nsTArray.h" // for nsTArray |
|
17 |
|
18 namespace tracked_objects { |
|
19 class Location; |
|
20 } |
|
21 |
|
22 namespace mozilla { |
|
23 namespace layers { |
|
24 |
|
25 /** The TaskThrottler prevents update event overruns. It is used in cases where |
|
26 * you're sending an async message and waiting for a reply. You need to call |
|
27 * PostTask to queue a task and TaskComplete when you get a response. |
|
28 * |
|
29 * The call to TaskComplete will run the recent task posted since the last |
|
30 * request was sent, if any. This means that at any time there can be at most 1 |
|
31 * outstanding request being processed and at most 1 queued behind it. |
|
32 * |
|
33 * This is used in the context of repainting a scrollable region. While another |
|
34 * process is painting you might get several updates from the UI thread but when |
|
35 * the paint is complete you want to send the most recent. |
|
36 */ |
|
37 |
|
38 class TaskThrottler { |
|
39 public: |
|
40 TaskThrottler(const TimeStamp& aTimeStamp); |
|
41 |
|
42 /** Post a task to be run as soon as there are no outstanding tasks. |
|
43 * |
|
44 * @param aLocation Use the macro FROM_HERE |
|
45 * @param aTask Ownership of this object is transferred to TaskThrottler |
|
46 * which will delete it when it is either run or becomes |
|
47 * obsolete or the TaskThrottler is destructed. |
|
48 */ |
|
49 void PostTask(const tracked_objects::Location& aLocation, |
|
50 CancelableTask* aTask, const TimeStamp& aTimeStamp); |
|
51 /** |
|
52 * Mark the task as complete and process the next queued task. |
|
53 */ |
|
54 void TaskComplete(const TimeStamp& aTimeStamp); |
|
55 |
|
56 /** |
|
57 * Calculate the average time between processing the posted task and getting |
|
58 * the TaskComplete() call back. |
|
59 */ |
|
60 TimeDuration AverageDuration() |
|
61 { |
|
62 return mMean.empty() ? TimeDuration() : mMean.mean(); |
|
63 } |
|
64 |
|
65 /** |
|
66 * return true if Throttler has an outstanding task |
|
67 */ |
|
68 bool IsOutstanding() { return mOutstanding; } |
|
69 |
|
70 /** |
|
71 * Return the time elapsed since the last request was processed |
|
72 */ |
|
73 TimeDuration TimeSinceLastRequest(const TimeStamp& aTimeStamp); |
|
74 |
|
75 /** |
|
76 * Clear average history. |
|
77 */ |
|
78 void ClearHistory() { mMean.clear(); } |
|
79 |
|
80 /** |
|
81 * @param aMaxDurations The maximum number of durations to measure. |
|
82 */ |
|
83 |
|
84 void SetMaxDurations(uint32_t aMaxDurations) |
|
85 { |
|
86 if (aMaxDurations != mMean.maxValues()) { |
|
87 mMean = RollingMean<TimeDuration, TimeDuration>(aMaxDurations); |
|
88 } |
|
89 } |
|
90 |
|
91 private: |
|
92 bool mOutstanding; |
|
93 nsAutoPtr<CancelableTask> mQueuedTask; |
|
94 TimeStamp mStartTime; |
|
95 RollingMean<TimeDuration, TimeDuration> mMean; |
|
96 }; |
|
97 |
|
98 } |
|
99 } |
|
100 |
|
101 #endif // mozilla_dom_TaskThrottler_h |