xpcom/tests/TestRacingServiceManager.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

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 }

mercurial