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 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #ifndef mozilla_IOInterposer_h
6 #define mozilla_IOInterposer_h
8 #include "mozilla/Attributes.h"
9 #include "mozilla/TimeStamp.h"
10 #include "mozilla/XPCOM.h"
12 namespace mozilla {
14 /**
15 * Interface for I/O interposer observers. This is separate from the
16 * IOInterposer because we have multiple uses for these observations.
17 */
18 class IOInterposeObserver
19 {
20 public:
21 enum Operation
22 {
23 OpNone = 0,
24 OpCreateOrOpen = (1 << 0),
25 OpRead = (1 << 1),
26 OpWrite = (1 << 2),
27 OpFSync = (1 << 3),
28 OpStat = (1 << 4),
29 OpClose = (1 << 5),
30 OpNextStage = (1 << 6), // Meta - used when leaving startup, entering shutdown
31 OpWriteFSync = (OpWrite | OpFSync),
32 OpAll = (OpCreateOrOpen | OpRead | OpWrite | OpFSync | OpStat | OpClose),
33 OpAllWithStaging = (OpAll | OpNextStage)
34 };
36 /** A representation of an I/O observation */
37 class Observation
38 {
39 protected:
40 /**
41 * This constructor is for use by subclasses that are intended to take
42 * timing measurements via RAII. The |aShouldReport| parameter may be
43 * used to make the measurement and reporting conditional on the
44 * satisfaction of an arbitrary predicate that was evaluated
45 * in the subclass. Note that IOInterposer::IsObservedOperation() is
46 * always ANDed with aShouldReport, so the subclass does not need to
47 * include a call to that function explicitly.
48 */
49 Observation(Operation aOperation, const char* aReference,
50 bool aShouldReport = true);
52 public:
53 /**
54 * Since this constructor accepts start and end times, it does *not* take
55 * its own timings, nor does it report itself.
56 */
57 Observation(Operation aOperation, const TimeStamp& aStart,
58 const TimeStamp& aEnd, const char* aReference);
60 /**
61 * Operation observed, this is one of the individual Operation values.
62 * Combinations of these flags are only used when registering observers.
63 */
64 Operation ObservedOperation() const
65 {
66 return mOperation;
67 }
69 /**
70 * Return the observed operation as a human-readable string.
71 */
72 const char* ObservedOperationString() const;
74 /** Time at which the I/O operation was started */
75 TimeStamp Start() const
76 {
77 return mStart;
78 }
80 /**
81 * Time at which the I/O operation ended, for asynchronous methods this is
82 * the time at which the call initiating the asynchronous request returned.
83 */
84 TimeStamp End() const
85 {
86 return mEnd;
87 }
89 /**
90 * Duration of the operation, for asynchronous I/O methods this is the
91 * duration of the call initiating the asynchronous request.
92 */
93 TimeDuration Duration() const
94 {
95 return mEnd - mStart;
96 }
98 /**
99 * IO reference, function name or name of component (sqlite) that did IO
100 * this is in addition the generic operation. This attribute may be platform
101 * specific, but should only take a finite number of distinct values.
102 * E.g. sqlite-commit, CreateFile, NtReadFile, fread, fsync, mmap, etc.
103 * I.e. typically the platform specific function that did the IO.
104 */
105 const char* Reference() const
106 {
107 return mReference;
108 }
110 /** Request filename associated with the I/O operation, null if unknown */
111 virtual const char16_t* Filename()
112 {
113 return nullptr;
114 }
116 virtual ~Observation()
117 {
118 }
120 protected:
121 void
122 Report();
124 Operation mOperation;
125 TimeStamp mStart;
126 TimeStamp mEnd;
127 const char* mReference; // Identifies the source of the Observation
128 bool mShouldReport; // Measure and report if true
129 };
131 /**
132 * Invoked whenever an implementation of the IOInterposeObserver should
133 * observe aObservation. Implement this and do your thing...
134 * But do consider if it is wise to use IO functions in this method, they are
135 * likely to cause recursion :)
136 * At least, see PoisonIOInterposer.h and register your handle as a debug file
137 * even, if you don't initialize the poison IO interposer, someone else might.
138 *
139 * Remark: Observations may occur on any thread.
140 */
141 virtual void Observe(Observation& aObservation) = 0;
143 virtual ~IOInterposeObserver()
144 {
145 }
147 protected:
148 /**
149 * We don't use NS_IsMainThread() because we need to be able to determine the
150 * main thread outside of XPCOM Initialization. IOInterposer observers should
151 * call this function instead.
152 */
153 static bool IsMainThread();
154 };
156 /**
157 * These functions are responsible for ensuring that events are routed to the
158 * appropriate observers.
159 */
160 namespace IOInterposer
161 {
162 /**
163 * This function must be called from the main-thread when no other threads are
164 * running before any of the other methods on this class may be used.
165 *
166 * IO reports can however, safely assume that IsObservedOperation() will
167 * return false until the IOInterposer is initialized.
168 *
169 * Remark, it's safe to call this method multiple times, so just call it when
170 * you to utilize IO interposing.
171 *
172 * Using the IOInterposerInit class is preferred to calling this directly.
173 */
174 bool Init();
176 /**
177 * This function must be called from the main thread, and furthermore
178 * it must be called when no other threads are executing. Effectively
179 * restricting us to calling it only during shutdown.
180 *
181 * Callers should take care that no other consumers are subscribed to events,
182 * as these events will stop when this function is called.
183 *
184 * In practice, we don't use this method as the IOInterposer is used for
185 * late-write checks.
186 */
187 void Clear();
189 /**
190 * This function immediately disables IOInterposer functionality in a fast,
191 * thread-safe manner. Primarily for use by the crash reporter.
192 */
193 void Disable();
195 /**
196 * Report IO to registered observers.
197 * Notice that the reported operation must be either OpRead, OpWrite or
198 * OpFSync. You are not allowed to report an observation with OpWriteFSync or
199 * OpAll, these are just auxiliary values for use with Register().
200 *
201 * If the IO call you're reporting does multiple things, write and fsync, you
202 * can choose to call Report() twice once with write and once with FSync. You
203 * may not call Report() with OpWriteFSync! The Observation::mOperation
204 * attribute is meant to be generic, not perfect.
205 *
206 * Notice that there is no reason to report an observation with an operation
207 * which is not being observed. Use IsObservedOperation() to check if the
208 * operation you are about to report is being observed. This is especially
209 * important if you are constructing expensive observations containing
210 * filename and full-path.
211 *
212 * Remark: Init() must be called before any IO is reported. But
213 * IsObservedOperation() will return false until Init() is called.
214 */
215 void Report(IOInterposeObserver::Observation& aObservation);
217 /**
218 * Return whether or not an operation is observed. Reporters should not
219 * report operations that are not being observed by anybody. This mechanism
220 * allows us to avoid reporting I/O when no observers are registered.
221 */
222 bool IsObservedOperation(IOInterposeObserver::Operation aOp);
224 /**
225 * Register IOInterposeObserver, the observer object will receive all
226 * observations for the given operation aOp.
227 *
228 * Remark: Init() must be called before observers are registered.
229 */
230 void Register(IOInterposeObserver::Operation aOp,
231 IOInterposeObserver* aObserver);
233 /**
234 * Unregister an IOInterposeObserver for a given operation
235 * Remark: It is always safe to unregister for all operations, even if yoú
236 * didn't register for them all.
237 * I.e. IOInterposer::Unregister(IOInterposeObserver::OpAll, aObserver)
238 *
239 * Remark: Init() must be called before observers are unregistered.
240 */
241 void Unregister(IOInterposeObserver::Operation aOp,
242 IOInterposeObserver* aObserver);
244 /**
245 * Registers the current thread with the IOInterposer. This must be done to
246 * ensure that per-thread data is created in an orderly fashion.
247 * We could have written this to initialize that data lazily, however this
248 * could have unintended consequences if a thread that is not aware of
249 * IOInterposer was implicitly registered: its per-thread data would never
250 * be deleted because it would not know to unregister itself.
251 *
252 * @param aIsMainThread true if IOInterposer should treat the current thread
253 * as the main thread.
254 */
255 void
256 RegisterCurrentThread(bool aIsMainThread = false);
258 /**
259 * Unregisters the current thread with the IOInterposer. This is important
260 * to call when a thread is shutting down because it cleans up data that
261 * is stored in a TLS slot.
262 */
263 void
264 UnregisterCurrentThread();
266 /**
267 * Called to inform observers that the process has transitioned out of the
268 * startup stage or into the shutdown stage. Main thread only.
269 */
270 void
271 EnteringNextStage();
272 } // namespace IOInterposer
274 class IOInterposerInit
275 {
276 public:
277 IOInterposerInit()
278 {
279 #if defined(MOZ_ENABLE_PROFILER_SPS)
280 IOInterposer::Init();
281 #endif
282 }
284 // No destructor needed at the moment -- this stuff stays active for the
285 // life of the process. This may change in the future.
286 };
288 } // namespace mozilla
290 #endif // mozilla_IOInterposer_h