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: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "TestHarness.h"
8 #include "nsIFactory.h"
9 #include "mozilla/Module.h"
10 #include "nsXULAppAPI.h"
11 #include "nsIThread.h"
12 #include "nsIComponentRegistrar.h"
14 #include "nsAutoPtr.h"
15 #include "nsThreadUtils.h"
16 #include "nsXPCOMCIDInternal.h"
17 #include "pratom.h"
18 #include "prmon.h"
19 #include "mozilla/Attributes.h"
21 #include "mozilla/ReentrantMonitor.h"
22 using namespace mozilla;
24 #ifdef DEBUG
25 #define TEST_ASSERTION(_test, _msg) \
26 NS_ASSERTION(_test, _msg);
27 #else
28 #define TEST_ASSERTION(_test, _msg) \
29 PR_BEGIN_MACRO \
30 if (!(_test)) { \
31 NS_DebugBreak(NS_DEBUG_ABORT, _msg, #_test, __FILE__, __LINE__); \
32 } \
33 PR_END_MACRO
34 #endif
36 /* f93f6bdc-88af-42d7-9d64-1b43c649a3e5 */
37 #define FACTORY_CID1 \
38 { \
39 0xf93f6bdc, \
40 0x88af, \
41 0x42d7, \
42 { 0x9d, 0x64, 0x1b, 0x43, 0xc6, 0x49, 0xa3, 0xe5 } \
43 }
44 NS_DEFINE_CID(kFactoryCID1, FACTORY_CID1);
46 /* ef38ad65-6595-49f0-8048-e819f81d15e2 */
47 #define FACTORY_CID2 \
48 { \
49 0xef38ad65, \
50 0x6595, \
51 0x49f0, \
52 { 0x80, 0x48, 0xe8, 0x19, 0xf8, 0x1d, 0x15, 0xe2 } \
53 }
54 NS_DEFINE_CID(kFactoryCID2, FACTORY_CID2);
56 #define FACTORY_CONTRACTID \
57 "TestRacingThreadManager/factory;1"
59 int32_t gComponent1Count = 0;
60 int32_t gComponent2Count = 0;
62 ReentrantMonitor* gReentrantMonitor = nullptr;
64 bool gCreateInstanceCalled = false;
65 bool gMainThreadWaiting = false;
67 class AutoCreateAndDestroyReentrantMonitor
68 {
69 public:
70 AutoCreateAndDestroyReentrantMonitor(ReentrantMonitor** aReentrantMonitorPtr)
71 : mReentrantMonitorPtr(aReentrantMonitorPtr) {
72 *aReentrantMonitorPtr =
73 new ReentrantMonitor("TestRacingServiceManager::AutoMon");
74 TEST_ASSERTION(*aReentrantMonitorPtr, "Out of memory!");
75 }
77 ~AutoCreateAndDestroyReentrantMonitor() {
78 if (*mReentrantMonitorPtr) {
79 delete *mReentrantMonitorPtr;
80 *mReentrantMonitorPtr = nullptr;
81 }
82 }
84 private:
85 ReentrantMonitor** mReentrantMonitorPtr;
86 };
88 class Factory MOZ_FINAL : public nsIFactory
89 {
90 public:
91 NS_DECL_THREADSAFE_ISUPPORTS
93 Factory() : mFirstComponentCreated(false) { }
95 NS_IMETHOD CreateInstance(nsISupports* aDelegate,
96 const nsIID& aIID,
97 void** aResult);
99 NS_IMETHOD LockFactory(bool aLock) {
100 return NS_OK;
101 }
103 bool mFirstComponentCreated;
104 };
106 NS_IMPL_ISUPPORTS(Factory, nsIFactory)
108 class Component1 MOZ_FINAL : public nsISupports
109 {
110 public:
111 NS_DECL_THREADSAFE_ISUPPORTS
113 Component1() {
114 // This is the real test - make sure that only one instance is ever created.
115 int32_t count = PR_AtomicIncrement(&gComponent1Count);
116 TEST_ASSERTION(count == 1, "Too many components created!");
117 }
118 };
120 NS_IMPL_ADDREF(Component1)
121 NS_IMPL_RELEASE(Component1)
123 NS_INTERFACE_MAP_BEGIN(Component1)
124 NS_INTERFACE_MAP_ENTRY(nsISupports)
125 NS_INTERFACE_MAP_END
127 class Component2 MOZ_FINAL : public nsISupports
128 {
129 public:
130 NS_DECL_THREADSAFE_ISUPPORTS
132 Component2() {
133 // This is the real test - make sure that only one instance is ever created.
134 int32_t count = PR_AtomicIncrement(&gComponent2Count);
135 TEST_ASSERTION(count == 1, "Too many components created!");
136 }
137 };
139 NS_IMPL_ADDREF(Component2)
140 NS_IMPL_RELEASE(Component2)
142 NS_INTERFACE_MAP_BEGIN(Component2)
143 NS_INTERFACE_MAP_ENTRY(nsISupports)
144 NS_INTERFACE_MAP_END
146 NS_IMETHODIMP
147 Factory::CreateInstance(nsISupports* aDelegate,
148 const nsIID& aIID,
149 void** aResult)
150 {
151 // Make sure that the second thread beat the main thread to the getService
152 // call.
153 TEST_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
155 {
156 ReentrantMonitorAutoEnter mon(*gReentrantMonitor);
158 gCreateInstanceCalled = true;
159 mon.Notify();
161 mon.Wait(PR_MillisecondsToInterval(3000));
162 }
164 NS_ENSURE_FALSE(aDelegate, NS_ERROR_NO_AGGREGATION);
165 NS_ENSURE_ARG_POINTER(aResult);
167 nsCOMPtr<nsISupports> instance;
169 if (!mFirstComponentCreated) {
170 instance = new Component1();
171 }
172 else {
173 instance = new Component2();
174 }
175 NS_ENSURE_TRUE(instance, NS_ERROR_OUT_OF_MEMORY);
177 nsresult rv = instance->QueryInterface(aIID, aResult);
178 NS_ENSURE_SUCCESS(rv, rv);
180 return NS_OK;
181 }
183 class Runnable : public nsRunnable
184 {
185 public:
186 NS_DECL_NSIRUNNABLE
188 Runnable() : mFirstRunnableDone(false) { }
190 bool mFirstRunnableDone;
191 };
193 NS_IMETHODIMP
194 Runnable::Run()
195 {
196 {
197 ReentrantMonitorAutoEnter mon(*gReentrantMonitor);
199 while (!gMainThreadWaiting) {
200 mon.Wait();
201 }
202 }
204 nsresult rv;
205 nsCOMPtr<nsISupports> component;
207 if (!mFirstRunnableDone) {
208 component = do_GetService(kFactoryCID1, &rv);
209 }
210 else {
211 component = do_GetService(FACTORY_CONTRACTID, &rv);
212 }
213 TEST_ASSERTION(NS_SUCCEEDED(rv), "GetService failed!");
215 return NS_OK;
216 }
218 static Factory* gFactory;
220 static already_AddRefed<nsIFactory>
221 CreateFactory(const mozilla::Module& module, const mozilla::Module::CIDEntry& entry)
222 {
223 if (!gFactory) {
224 gFactory = new Factory();
225 NS_ADDREF(gFactory);
226 }
227 nsCOMPtr<nsIFactory> ret = gFactory;
228 return ret.forget();
229 }
231 static const mozilla::Module::CIDEntry kLocalCIDs[] = {
232 { &kFactoryCID1, false, CreateFactory, nullptr },
233 { &kFactoryCID2, false, CreateFactory, nullptr },
234 { nullptr }
235 };
237 static const mozilla::Module::ContractIDEntry kLocalContracts[] = {
238 { FACTORY_CONTRACTID, &kFactoryCID2 },
239 { nullptr }
240 };
242 static const mozilla::Module kLocalModule = {
243 mozilla::Module::kVersion,
244 kLocalCIDs,
245 kLocalContracts
246 };
248 int main(int argc, char** argv)
249 {
250 nsresult rv;
251 XRE_AddStaticComponent(&kLocalModule);
253 ScopedXPCOM xpcom("RacingServiceManager");
254 NS_ENSURE_FALSE(xpcom.failed(), 1);
256 AutoCreateAndDestroyReentrantMonitor mon(&gReentrantMonitor);
258 nsRefPtr<Runnable> runnable = new Runnable();
259 NS_ENSURE_TRUE(runnable, 1);
261 // Run the classID test
262 nsCOMPtr<nsIThread> newThread;
263 rv = NS_NewThread(getter_AddRefs(newThread), runnable);
264 NS_ENSURE_SUCCESS(rv, 1);
266 {
267 ReentrantMonitorAutoEnter mon(*gReentrantMonitor);
269 gMainThreadWaiting = true;
270 mon.Notify();
272 while (!gCreateInstanceCalled) {
273 mon.Wait();
274 }
275 }
277 nsCOMPtr<nsISupports> component(do_GetService(kFactoryCID1, &rv));
278 NS_ENSURE_SUCCESS(rv, 1);
280 // Reset for the contractID test
281 gMainThreadWaiting = gCreateInstanceCalled = false;
282 gFactory->mFirstComponentCreated = runnable->mFirstRunnableDone = true;
283 component = nullptr;
285 rv = newThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
286 NS_ENSURE_SUCCESS(rv, 1);
288 {
289 ReentrantMonitorAutoEnter mon(*gReentrantMonitor);
291 gMainThreadWaiting = true;
292 mon.Notify();
294 while (!gCreateInstanceCalled) {
295 mon.Wait();
296 }
297 }
299 component = do_GetService(FACTORY_CONTRACTID, &rv);
300 NS_ENSURE_SUCCESS(rv, 1);
302 NS_RELEASE(gFactory);
304 return 0;
305 }