Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
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/. */
7 #ifndef mozilla_TimeStamp_h
8 #define mozilla_TimeStamp_h
10 #include <stdint.h>
11 #include "mozilla/Assertions.h"
12 #include "mozilla/Attributes.h"
13 #include "nscore.h"
15 namespace IPC {
16 template <typename T> struct ParamTraits;
17 }
19 #ifdef XP_WIN
20 // defines TimeStampValue as a complex value keeping both
21 // GetTickCount and QueryPerformanceCounter values
22 #include "TimeStamp_windows.h"
23 #endif
25 namespace mozilla {
27 #ifndef XP_WIN
28 typedef uint64_t TimeStampValue;
29 #endif
31 class TimeStamp;
33 /**
34 * Instances of this class represent the length of an interval of time.
35 * Negative durations are allowed, meaning the end is before the start.
36 *
37 * Internally the duration is stored as a int64_t in units of
38 * PR_TicksPerSecond() when building with NSPR interval timers, or a
39 * system-dependent unit when building with system clocks. The
40 * system-dependent unit must be constant, otherwise the semantics of
41 * this class would be broken.
42 */
43 class TimeDuration
44 {
45 public:
46 // The default duration is 0.
47 MOZ_CONSTEXPR TimeDuration() : mValue(0) {}
48 // Allow construction using '0' as the initial value, for readability,
49 // but no other numbers (so we don't have any implicit unit conversions).
50 struct _SomethingVeryRandomHere;
51 TimeDuration(_SomethingVeryRandomHere* aZero) : mValue(0) {
52 MOZ_ASSERT(!aZero, "Who's playing funny games here?");
53 }
54 // Default copy-constructor and assignment are OK
56 double ToSeconds() const;
57 // Return a duration value that includes digits of time we think to
58 // be significant. This method should be used when displaying a
59 // time to humans.
60 double ToSecondsSigDigits() const;
61 double ToMilliseconds() const {
62 return ToSeconds() * 1000.0;
63 }
64 double ToMicroseconds() const {
65 return ToMilliseconds() * 1000.0;
66 }
68 // Using a double here is safe enough; with 53 bits we can represent
69 // durations up to over 280,000 years exactly. If the units of
70 // mValue do not allow us to represent durations of that length,
71 // long durations are clamped to the max/min representable value
72 // instead of overflowing.
73 static inline TimeDuration FromSeconds(double aSeconds) {
74 return FromMilliseconds(aSeconds * 1000.0);
75 }
76 static TimeDuration FromMilliseconds(double aMilliseconds);
77 static inline TimeDuration FromMicroseconds(double aMicroseconds) {
78 return FromMilliseconds(aMicroseconds / 1000.0);
79 }
81 static TimeDuration Forever() {
82 return FromTicks(INT64_MAX);
83 }
85 TimeDuration operator+(const TimeDuration& aOther) const {
86 return TimeDuration::FromTicks(mValue + aOther.mValue);
87 }
88 TimeDuration operator-(const TimeDuration& aOther) const {
89 return TimeDuration::FromTicks(mValue - aOther.mValue);
90 }
91 TimeDuration& operator+=(const TimeDuration& aOther) {
92 mValue += aOther.mValue;
93 return *this;
94 }
95 TimeDuration& operator-=(const TimeDuration& aOther) {
96 mValue -= aOther.mValue;
97 return *this;
98 }
100 private:
101 // Block double multiplier (slower, imprecise if long duration) - Bug 853398.
102 // If required, use MultDouble explicitly and with care.
103 TimeDuration operator*(const double aMultiplier) const MOZ_DELETE;
105 public:
106 TimeDuration MultDouble(double aMultiplier) const {
107 return TimeDuration::FromTicks(static_cast<int64_t>(mValue * aMultiplier));
108 }
109 TimeDuration operator*(const int32_t aMultiplier) const {
110 return TimeDuration::FromTicks(mValue * int64_t(aMultiplier));
111 }
112 TimeDuration operator*(const uint32_t aMultiplier) const {
113 return TimeDuration::FromTicks(mValue * int64_t(aMultiplier));
114 }
115 TimeDuration operator*(const int64_t aMultiplier) const {
116 return TimeDuration::FromTicks(mValue * int64_t(aMultiplier));
117 }
118 TimeDuration operator/(const int64_t aDivisor) const {
119 return TimeDuration::FromTicks(mValue / aDivisor);
120 }
121 double operator/(const TimeDuration& aOther) const {
122 return static_cast<double>(mValue) / aOther.mValue;
123 }
125 bool operator<(const TimeDuration& aOther) const {
126 return mValue < aOther.mValue;
127 }
128 bool operator<=(const TimeDuration& aOther) const {
129 return mValue <= aOther.mValue;
130 }
131 bool operator>=(const TimeDuration& aOther) const {
132 return mValue >= aOther.mValue;
133 }
134 bool operator>(const TimeDuration& aOther) const {
135 return mValue > aOther.mValue;
136 }
137 bool operator==(const TimeDuration& aOther) const {
138 return mValue == aOther.mValue;
139 }
141 // Return a best guess at the system's current timing resolution,
142 // which might be variable. TimeDurations below this order of
143 // magnitude are meaningless, and those at the same order of
144 // magnitude or just above are suspect.
145 static TimeDuration Resolution();
147 // We could define additional operators here:
148 // -- convert to/from other time units
149 // -- scale duration by a float
150 // but let's do that on demand.
151 // Comparing durations for equality will only lead to bugs on
152 // platforms with high-resolution timers.
154 private:
155 friend class TimeStamp;
156 friend struct IPC::ParamTraits<mozilla::TimeDuration>;
158 static TimeDuration FromTicks(int64_t aTicks) {
159 TimeDuration t;
160 t.mValue = aTicks;
161 return t;
162 }
164 static TimeDuration FromTicks(double aTicks) {
165 // NOTE: this MUST be a >= test, because int64_t(double(INT64_MAX))
166 // overflows and gives INT64_MIN.
167 if (aTicks >= double(INT64_MAX))
168 return TimeDuration::FromTicks(INT64_MAX);
170 // This MUST be a <= test.
171 if (aTicks <= double(INT64_MIN))
172 return TimeDuration::FromTicks(INT64_MIN);
174 return TimeDuration::FromTicks(int64_t(aTicks));
175 }
177 // Duration, result is implementation-specific difference of two TimeStamps
178 int64_t mValue;
179 };
181 /**
182 * Instances of this class represent moments in time, or a special
183 * "null" moment. We do not use the non-monotonic system clock or
184 * local time, since they can be reset, causing apparent backward
185 * travel in time, which can confuse algorithms. Instead we measure
186 * elapsed time according to the system. This time can never go
187 * backwards (i.e. it never wraps around, at least not in less than
188 * five million years of system elapsed time). It might not advance
189 * while the system is sleeping. If TimeStamp::SetNow() is not called
190 * at all for hours or days, we might not notice the passage of some
191 * of that time.
192 *
193 * We deliberately do not expose a way to convert TimeStamps to some
194 * particular unit. All you can do is compute a difference between two
195 * TimeStamps to get a TimeDuration. You can also add a TimeDuration
196 * to a TimeStamp to get a new TimeStamp. You can't do something
197 * meaningless like add two TimeStamps.
198 *
199 * Internally this is implemented as either a wrapper around
200 * - high-resolution, monotonic, system clocks if they exist on this
201 * platform
202 * - PRIntervalTime otherwise. We detect wraparounds of
203 * PRIntervalTime and work around them.
204 *
205 * This class is similar to C++11's time_point, however it is
206 * explicitly nullable and provides an IsNull() method. time_point
207 * is initialized to the clock's epoch and provides a
208 * time_since_epoch() method that functions similiarly. i.e.
209 * t.IsNull() is equivalent to t.time_since_epoch() == decltype(t)::duration::zero();
210 */
211 class TimeStamp
212 {
213 public:
214 /**
215 * Initialize to the "null" moment
216 */
217 MOZ_CONSTEXPR TimeStamp() : mValue(0) {}
218 // Default copy-constructor and assignment are OK
220 /**
221 * Return true if this is the "null" moment
222 */
223 bool IsNull() const { return mValue == 0; }
224 /**
225 * Return a timestamp reflecting the current elapsed system time. This
226 * is monotonically increasing (i.e., does not decrease) over the
227 * lifetime of this process' XPCOM session.
228 *
229 * Now() is trying to ensure the best possible precision on each platform,
230 * at least one millisecond.
231 *
232 * NowLoRes() has been introduced to workaround performance problems of
233 * QueryPerformanceCounter on the Windows platform. NowLoRes() is giving
234 * lower precision, usually 15.6 ms, but with very good performance benefit.
235 * Use it for measurements of longer times, like >200ms timeouts.
236 */
237 static TimeStamp Now() { return Now(true); }
238 static TimeStamp NowLoRes() { return Now(false); }
240 /**
241 * Return a timestamp representing the time when the current process was
242 * created which will be comparable with other timestamps taken with this
243 * class. If the actual process creation time is detected to be inconsistent
244 * the @a aIsInconsistent parameter will be set to true, the returned
245 * timestamp however will still be valid though inaccurate.
246 *
247 * @param aIsInconsistent Set to true if an inconsistency was detected in the
248 * process creation time
249 * @returns A timestamp representing the time when the process was created,
250 * this timestamp is always valid even when errors are reported
251 */
252 static TimeStamp ProcessCreation(bool& aIsInconsistent);
254 /**
255 * Records a process restart. After this call ProcessCreation() will return
256 * the time when the browser was restarted instead of the actual time when
257 * the process was created.
258 */
259 static void RecordProcessRestart();
261 /**
262 * Compute the difference between two timestamps. Both must be non-null.
263 */
264 TimeDuration operator-(const TimeStamp& aOther) const {
265 MOZ_ASSERT(!IsNull(), "Cannot compute with a null value");
266 MOZ_ASSERT(!aOther.IsNull(), "Cannot compute with aOther null value");
267 static_assert(-INT64_MAX > INT64_MIN, "int64_t sanity check");
268 int64_t ticks = int64_t(mValue - aOther.mValue);
269 // Check for overflow.
270 if (mValue > aOther.mValue) {
271 if (ticks < 0) {
272 ticks = INT64_MAX;
273 }
274 } else {
275 if (ticks > 0) {
276 ticks = INT64_MIN;
277 }
278 }
279 return TimeDuration::FromTicks(ticks);
280 }
282 TimeStamp operator+(const TimeDuration& aOther) const {
283 MOZ_ASSERT(!IsNull(), "Cannot compute with a null value");
284 return TimeStamp(mValue + aOther.mValue);
285 }
286 TimeStamp operator-(const TimeDuration& aOther) const {
287 MOZ_ASSERT(!IsNull(), "Cannot compute with a null value");
288 return TimeStamp(mValue - aOther.mValue);
289 }
290 TimeStamp& operator+=(const TimeDuration& aOther) {
291 MOZ_ASSERT(!IsNull(), "Cannot compute with a null value");
292 mValue += aOther.mValue;
293 return *this;
294 }
295 TimeStamp& operator-=(const TimeDuration& aOther) {
296 MOZ_ASSERT(!IsNull(), "Cannot compute with a null value");
297 mValue -= aOther.mValue;
298 return *this;
299 }
301 bool operator<(const TimeStamp& aOther) const {
302 MOZ_ASSERT(!IsNull(), "Cannot compute with a null value");
303 MOZ_ASSERT(!aOther.IsNull(), "Cannot compute with aOther null value");
304 return mValue < aOther.mValue;
305 }
306 bool operator<=(const TimeStamp& aOther) const {
307 MOZ_ASSERT(!IsNull(), "Cannot compute with a null value");
308 MOZ_ASSERT(!aOther.IsNull(), "Cannot compute with aOther null value");
309 return mValue <= aOther.mValue;
310 }
311 bool operator>=(const TimeStamp& aOther) const {
312 MOZ_ASSERT(!IsNull(), "Cannot compute with a null value");
313 MOZ_ASSERT(!aOther.IsNull(), "Cannot compute with aOther null value");
314 return mValue >= aOther.mValue;
315 }
316 bool operator>(const TimeStamp& aOther) const {
317 MOZ_ASSERT(!IsNull(), "Cannot compute with a null value");
318 MOZ_ASSERT(!aOther.IsNull(), "Cannot compute with aOther null value");
319 return mValue > aOther.mValue;
320 }
321 bool operator==(const TimeStamp& aOther) const {
322 // Maybe it's ok to check == with null timestamps?
323 MOZ_ASSERT(!IsNull() && "Cannot compute with a null value");
324 MOZ_ASSERT(!aOther.IsNull(), "Cannot compute with aOther null value");
325 return mValue == aOther.mValue;
326 }
327 bool operator!=(const TimeStamp& aOther) const {
328 // Maybe it's ok to check != with null timestamps?
329 MOZ_ASSERT(!IsNull(), "Cannot compute with a null value");
330 MOZ_ASSERT(!aOther.IsNull(), "Cannot compute with aOther null value");
331 return mValue != aOther.mValue;
332 }
334 // Comparing TimeStamps for equality should be discouraged. Adding
335 // two TimeStamps, or scaling TimeStamps, is nonsense and must never
336 // be allowed.
338 static NS_HIDDEN_(nsresult) Startup();
339 static NS_HIDDEN_(void) Shutdown();
341 private:
342 friend struct IPC::ParamTraits<mozilla::TimeStamp>;
343 friend void StartupTimelineRecordExternal(int, uint64_t);
345 TimeStamp(TimeStampValue aValue) : mValue(aValue) {}
347 static TimeStamp Now(bool aHighResolution);
349 /**
350 * Computes the uptime of the current process in microseconds. The result
351 * is platform-dependent and needs to be checked against existing timestamps
352 * for consistency.
353 *
354 * @returns The number of microseconds since the calling process was started
355 * or 0 if an error was encountered while computing the uptime
356 */
357 static uint64_t ComputeProcessUptime();
359 /**
360 * When built with PRIntervalTime, a value of 0 means this instance
361 * is "null". Otherwise, the low 32 bits represent a PRIntervalTime,
362 * and the high 32 bits represent a counter of the number of
363 * rollovers of PRIntervalTime that we've seen. This counter starts
364 * at 1 to avoid a real time colliding with the "null" value.
365 *
366 * PR_INTERVAL_MAX is set at 100,000 ticks per second. So the minimum
367 * time to wrap around is about 2^64/100000 seconds, i.e. about
368 * 5,849,424 years.
369 *
370 * When using a system clock, a value is system dependent.
371 */
372 TimeStampValue mValue;
373 };
375 }
377 #endif /* mozilla_TimeStamp_h */