xpcom/tests/TestThreadPoolListener.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 "nsIThread.h"
     9 #include "nsIThreadPool.h"
    11 #include "nsThreadUtils.h"
    12 #include "nsXPCOMCIDInternal.h"
    13 #include "pratom.h"
    14 #include "prinrval.h"
    15 #include "prmon.h"
    16 #include "prthread.h"
    17 #include "mozilla/Attributes.h"
    19 #include "mozilla/ReentrantMonitor.h"
    20 using namespace mozilla;
    22 #define NUMBER_OF_THREADS 4
    24 // One hour... because test boxes can be slow!
    25 #define IDLE_THREAD_TIMEOUT 3600000
    27 static nsIThread** gCreatedThreadList = nullptr;
    28 static nsIThread** gShutDownThreadList = nullptr;
    30 static ReentrantMonitor* gReentrantMonitor = nullptr;
    32 static bool gAllRunnablesPosted = false;
    33 static bool gAllThreadsCreated = false;
    34 static bool gAllThreadsShutDown = false;
    36 #ifdef DEBUG
    37 #define TEST_ASSERTION(_test, _msg) \
    38     NS_ASSERTION(_test, _msg);
    39 #else
    40 #define TEST_ASSERTION(_test, _msg) \
    41   PR_BEGIN_MACRO \
    42     if (!(_test)) { \
    43       NS_DebugBreak(NS_DEBUG_ABORT, _msg, #_test, __FILE__, __LINE__); \
    44     } \
    45   PR_END_MACRO
    46 #endif
    48 class Listener MOZ_FINAL : public nsIThreadPoolListener
    49 {
    50 public:
    51   NS_DECL_THREADSAFE_ISUPPORTS
    52   NS_DECL_NSITHREADPOOLLISTENER
    53 };
    55 NS_IMPL_ISUPPORTS(Listener, nsIThreadPoolListener)
    57 NS_IMETHODIMP
    58 Listener::OnThreadCreated()
    59 {
    60   nsCOMPtr<nsIThread> current(do_GetCurrentThread());
    61   TEST_ASSERTION(current, "Couldn't get current thread!");
    63   ReentrantMonitorAutoEnter mon(*gReentrantMonitor);
    65   while (!gAllRunnablesPosted) {
    66     mon.Wait();
    67   }
    69   for (uint32_t i = 0; i < NUMBER_OF_THREADS; i++) {
    70     nsIThread* thread = gCreatedThreadList[i];
    71     TEST_ASSERTION(thread != current, "Saw the same thread twice!");
    73     if (!thread) {
    74       gCreatedThreadList[i] = current;
    75       if (i == (NUMBER_OF_THREADS - 1)) {
    76         gAllThreadsCreated = true;
    77         mon.NotifyAll();
    78       }
    79       return NS_OK;
    80     }
    81   }
    83   TEST_ASSERTION(false, "Too many threads!");
    84   return NS_ERROR_FAILURE;
    85 }
    87 NS_IMETHODIMP
    88 Listener::OnThreadShuttingDown()
    89 {
    90   nsCOMPtr<nsIThread> current(do_GetCurrentThread());
    91   TEST_ASSERTION(current, "Couldn't get current thread!");
    93   ReentrantMonitorAutoEnter mon(*gReentrantMonitor);
    95   for (uint32_t i = 0; i < NUMBER_OF_THREADS; i++) {
    96     nsIThread* thread = gShutDownThreadList[i];
    97     TEST_ASSERTION(thread != current, "Saw the same thread twice!");
    99     if (!thread) {
   100       gShutDownThreadList[i] = current;
   101       if (i == (NUMBER_OF_THREADS - 1)) {
   102         gAllThreadsShutDown = true;
   103         mon.NotifyAll();
   104       }
   105       return NS_OK;
   106     }
   107   }
   109   TEST_ASSERTION(false, "Too many threads!");
   110   return NS_ERROR_FAILURE;
   111 }
   113 class AutoCreateAndDestroyReentrantMonitor
   114 {
   115 public:
   116   AutoCreateAndDestroyReentrantMonitor(ReentrantMonitor** aReentrantMonitorPtr)
   117   : mReentrantMonitorPtr(aReentrantMonitorPtr) {
   118     *aReentrantMonitorPtr = new ReentrantMonitor("TestThreadPoolListener::AutoMon");
   119     TEST_ASSERTION(*aReentrantMonitorPtr, "Out of memory!");
   120   }
   122   ~AutoCreateAndDestroyReentrantMonitor() {
   123     if (*mReentrantMonitorPtr) {
   124       delete *mReentrantMonitorPtr;
   125       *mReentrantMonitorPtr = nullptr;
   126     }
   127   }
   129 private:
   130   ReentrantMonitor** mReentrantMonitorPtr;
   131 };
   133 int main(int argc, char** argv)
   134 {
   135   ScopedXPCOM xpcom("ThreadPoolListener");
   136   NS_ENSURE_FALSE(xpcom.failed(), 1);
   138   nsIThread* createdThreadList[NUMBER_OF_THREADS] = { nullptr };
   139   gCreatedThreadList = createdThreadList;
   141   nsIThread* shutDownThreadList[NUMBER_OF_THREADS] = { nullptr };
   142   gShutDownThreadList = shutDownThreadList;
   144   AutoCreateAndDestroyReentrantMonitor newMon(&gReentrantMonitor);
   145   NS_ENSURE_TRUE(gReentrantMonitor, 1);
   147   nsresult rv;
   149   nsCOMPtr<nsIThreadPool> pool =
   150     do_CreateInstance(NS_THREADPOOL_CONTRACTID, &rv);
   151   NS_ENSURE_SUCCESS(rv, 1);
   153   rv = pool->SetThreadLimit(NUMBER_OF_THREADS);
   154   NS_ENSURE_SUCCESS(rv, 1);
   156   rv = pool->SetIdleThreadLimit(NUMBER_OF_THREADS);
   157   NS_ENSURE_SUCCESS(rv, 1);
   159   rv = pool->SetIdleThreadTimeout(IDLE_THREAD_TIMEOUT);
   160   NS_ENSURE_SUCCESS(rv, 1);
   162   nsCOMPtr<nsIThreadPoolListener> listener = new Listener();
   163   NS_ENSURE_TRUE(listener, 1);
   165   rv = pool->SetListener(listener);
   166   NS_ENSURE_SUCCESS(rv, 1);
   168   {
   169     ReentrantMonitorAutoEnter mon(*gReentrantMonitor);
   171     for (uint32_t i = 0; i < NUMBER_OF_THREADS; i++) {
   172       nsCOMPtr<nsIRunnable> runnable = new nsRunnable();
   173       NS_ENSURE_TRUE(runnable, 1);
   175       rv = pool->Dispatch(runnable, NS_DISPATCH_NORMAL);
   176       NS_ENSURE_SUCCESS(rv, 1);
   177     }
   179     gAllRunnablesPosted = true;
   180     mon.NotifyAll();
   181   }
   183   {
   184     ReentrantMonitorAutoEnter mon(*gReentrantMonitor);
   185     while (!gAllThreadsCreated) {
   186       mon.Wait();
   187     }
   188   }
   190   rv = pool->Shutdown();
   191   NS_ENSURE_SUCCESS(rv, 1);
   193   {
   194     ReentrantMonitorAutoEnter mon(*gReentrantMonitor);
   195     while (!gAllThreadsShutDown) {
   196       mon.Wait();
   197     }
   198   }
   200   for (uint32_t i = 0; i < NUMBER_OF_THREADS; i++) {
   201     nsIThread* created = gCreatedThreadList[i];
   202     NS_ENSURE_TRUE(created, 1);
   204     bool match = false;
   205     for (uint32_t j = 0; j < NUMBER_OF_THREADS; j++) {
   206       nsIThread* destroyed = gShutDownThreadList[j];
   207       NS_ENSURE_TRUE(destroyed, 1);
   209       if (destroyed == created) {
   210         match = true;
   211         break;
   212       }
   213     }
   215     NS_ENSURE_TRUE(match, 1);
   216   }
   218   return 0;
   219 }

mercurial