xpcom/tests/TestSynchronization.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: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2  * vim: sw=4 ts=4 et :
     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 #include "TestHarness.h"
     9 #include "mozilla/CondVar.h"
    10 #include "mozilla/Monitor.h"
    11 #include "mozilla/Mutex.h"
    12 #include "nsAutoLock.h"
    14 using namespace mozilla;
    16 static PRThread*
    17 spawn(void (*run)(void*), void* arg)
    18 {
    19     return PR_CreateThread(PR_SYSTEM_THREAD,
    20                            run,
    21                            arg,
    22                            PR_PRIORITY_NORMAL,
    23                            PR_GLOBAL_THREAD,
    24                            PR_JOINABLE_THREAD,
    25                            0);
    26 }
    29 #define PASS()                                  \
    30     do {                                        \
    31         passed(__FUNCTION__);                   \
    32         return NS_OK;                           \
    33     } while (0)
    35 #define FAIL(why)                               \
    36     do {                                        \
    37         fail("%s | %s - %s", __FILE__, __FUNCTION__, why); \
    38         return NS_ERROR_FAILURE;                \
    39     } while (0)
    41 //-----------------------------------------------------------------------------
    42 // Sanity check: tests that can be done on a single thread
    43 //
    44 static nsresult
    45 Sanity()
    46 {
    47     Mutex lock("sanity::lock");
    48     lock.Lock();
    49     lock.AssertCurrentThreadOwns();
    50     lock.Unlock();
    52     {
    53         MutexAutoLock autolock(lock);
    54         lock.AssertCurrentThreadOwns();
    55     }
    57     lock.Lock();
    58     lock.AssertCurrentThreadOwns();
    59     {
    60         MutexAutoUnlock autounlock(lock);
    61     }
    62     lock.AssertCurrentThreadOwns();
    63     lock.Unlock();
    65     Monitor mon("sanity::monitor");
    66     mon.Enter();
    67     mon.AssertCurrentThreadIn();
    68     mon.Enter();
    69     mon.AssertCurrentThreadIn();
    70     mon.Exit();
    71     mon.AssertCurrentThreadIn();
    72     mon.Exit();
    74     {
    75         MonitorAutoEnter automon(mon);
    76         mon.AssertCurrentThreadIn();
    77     }
    79     PASS();
    80 }
    82 //-----------------------------------------------------------------------------
    83 // Mutex contention tests
    84 //
    85 static Mutex* gLock1;
    87 static void
    88 MutexContention_thread(void* /*arg*/)
    89 {
    90     for (int i = 0; i < 100000; ++i) {
    91         gLock1->Lock();
    92         gLock1->AssertCurrentThreadOwns();
    93         gLock1->Unlock();
    94     }
    95 }
    97 static nsresult
    98 MutexContention()
    99 {
   100     gLock1 = new Mutex("lock1");
   101     // PURPOSELY not checking for OOM.  YAY!
   103     PRThread* t1 = spawn(MutexContention_thread, nullptr);
   104     PRThread* t2 = spawn(MutexContention_thread, nullptr);
   105     PRThread* t3 = spawn(MutexContention_thread, nullptr);
   107     PR_JoinThread(t1);
   108     PR_JoinThread(t2);
   109     PR_JoinThread(t3);
   111     delete gLock1;
   113     PASS();
   114 }
   116 //-----------------------------------------------------------------------------
   117 // Monitor tests
   118 //
   119 static Monitor* gMon1;
   121 static void
   122 MonitorContention_thread(void* /*arg*/)
   123 {
   124     for (int i = 0; i < 100000; ++i) {
   125         gMon1->Enter();
   126         gMon1->AssertCurrentThreadIn();
   127         gMon1->Exit();
   128     }
   129 }
   131 static nsresult
   132 MonitorContention()
   133 {
   134     gMon1 = new Monitor("mon1");
   136     PRThread* t1 = spawn(MonitorContention_thread, nullptr);
   137     PRThread* t2 = spawn(MonitorContention_thread, nullptr);
   138     PRThread* t3 = spawn(MonitorContention_thread, nullptr);
   140     PR_JoinThread(t1);
   141     PR_JoinThread(t2);
   142     PR_JoinThread(t3);
   144     delete gMon1;
   146     PASS();
   147 }
   150 static Monitor* gMon2;
   152 static void
   153 MonitorContention2_thread(void* /*arg*/)
   154 {
   155     for (int i = 0; i < 100000; ++i) {
   156         gMon2->Enter();
   157         gMon2->AssertCurrentThreadIn();
   158         {
   159             gMon2->Enter();
   160             gMon2->AssertCurrentThreadIn();
   161             gMon2->Exit();
   162         }
   163         gMon2->AssertCurrentThreadIn();
   164         gMon2->Exit();
   165     }
   166 }
   168 static nsresult
   169 MonitorContention2()
   170 {
   171     gMon2 = new Monitor("mon1");
   173     PRThread* t1 = spawn(MonitorContention2_thread, nullptr);
   174     PRThread* t2 = spawn(MonitorContention2_thread, nullptr);
   175     PRThread* t3 = spawn(MonitorContention2_thread, nullptr);
   177     PR_JoinThread(t1);
   178     PR_JoinThread(t2);
   179     PR_JoinThread(t3);
   181     delete gMon2;
   183     PASS();
   184 }
   187 static Monitor* gMon3;
   188 static int32_t gMonFirst;
   190 static void
   191 MonitorSyncSanity_thread(void* /*arg*/)
   192 {
   193     gMon3->Enter();
   194     gMon3->AssertCurrentThreadIn();
   195     if (gMonFirst) {
   196         gMonFirst = 0;
   197         gMon3->Wait();
   198         gMon3->Enter();
   199     } else {
   200         gMon3->Notify();
   201         gMon3->Enter();
   202     }
   203     gMon3->AssertCurrentThreadIn();
   204     gMon3->Exit();
   205     gMon3->AssertCurrentThreadIn();
   206     gMon3->Exit();
   207 }
   209 static nsresult
   210 MonitorSyncSanity()
   211 {
   212     gMon3 = new Monitor("monitor::syncsanity");
   214     for (int32_t i = 0; i < 10000; ++i) {
   215         gMonFirst = 1;
   216         PRThread* ping = spawn(MonitorSyncSanity_thread, nullptr);
   217         PRThread* pong = spawn(MonitorSyncSanity_thread, nullptr);
   218         PR_JoinThread(ping);
   219         PR_JoinThread(pong);
   220     }
   222     delete gMon3;
   224     PASS();
   225 }
   227 //-----------------------------------------------------------------------------
   228 // Condvar tests
   229 //
   230 static Mutex* gCvlock1;
   231 static CondVar* gCv1;
   232 static int32_t gCvFirst;
   234 static void
   235 CondVarSanity_thread(void* /*arg*/)
   236 {
   237     gCvlock1->Lock();
   238     gCvlock1->AssertCurrentThreadOwns();
   239     if (gCvFirst) {
   240         gCvFirst = 0;
   241         gCv1->Wait();
   242     } else {
   243         gCv1->Notify();
   244     }
   245     gCvlock1->AssertCurrentThreadOwns();
   246     gCvlock1->Unlock();
   247 }
   249 static nsresult
   250 CondVarSanity()
   251 {
   252     gCvlock1 = new Mutex("cvlock1");
   253     gCv1 = new CondVar(*gCvlock1, "cvlock1");
   255     for (int32_t i = 0; i < 10000; ++i) {
   256         gCvFirst = 1;
   257         PRThread* ping = spawn(CondVarSanity_thread, nullptr);
   258         PRThread* pong = spawn(CondVarSanity_thread, nullptr);
   259         PR_JoinThread(ping);
   260         PR_JoinThread(pong);
   261     }
   263     delete gCv1;
   264     delete gCvlock1;
   266     PASS();
   267 }
   269 //-----------------------------------------------------------------------------
   270 // AutoLock tests
   271 //
   272 static nsresult
   273 AutoLock()
   274 {
   275     Mutex l1("autolock");
   276     MutexAutoLock autol1(l1);
   278     l1.AssertCurrentThreadOwns();
   280     {
   281         Mutex l2("autolock2");
   282         MutexAutoLock autol2(l2);
   284         l1.AssertCurrentThreadOwns();
   285         l2.AssertCurrentThreadOwns();
   286     }
   288     l1.AssertCurrentThreadOwns();
   290     PASS();
   291 }
   293 //-----------------------------------------------------------------------------
   294 // AutoUnlock tests
   295 //
   296 static nsresult
   297 AutoUnlock()
   298 {
   299     Mutex l1("autounlock");
   300     Mutex l2("autounlock2");
   302     l1.Lock();
   303     l1.AssertCurrentThreadOwns();
   305     {
   306         MutexAutoUnlock autol1(l1);
   307         {
   308             l2.Lock();
   309             l2.AssertCurrentThreadOwns();
   311             MutexAutoUnlock autol2(l2);
   312         }
   313         l2.AssertCurrentThreadOwns();
   314         l2.Unlock();
   315     }
   316     l1.AssertCurrentThreadOwns();
   318     l1.Unlock();
   320     PASS();
   321 }
   323 //-----------------------------------------------------------------------------
   324 // AutoMonitor tests
   325 //
   326 static nsresult
   327 AutoMonitor()
   328 {
   329     Monitor m1("automonitor");
   330     Monitor m2("automonitor2");
   332     m1.Enter();
   333     m1.AssertCurrentThreadIn();
   334     {
   335         MonitorAutoEnter autom1(m1);
   336         m1.AssertCurrentThreadIn();
   338         m2.Enter();
   339         m2.AssertCurrentThreadIn();
   340         {
   341             MonitorAutoEnter autom2(m2);
   342             m1.AssertCurrentThreadIn();
   343             m2.AssertCurrentThreadIn();
   344         }
   345         m2.AssertCurrentThreadIn();
   346         m2.Exit();
   348         m1.AssertCurrentThreadIn();
   349     }
   350     m1.AssertCurrentThreadIn();
   351     m1.Exit();
   353     PASS();
   354 }
   356 //-----------------------------------------------------------------------------
   358 int
   359 main(int argc, char** argv)
   360 {
   361     ScopedXPCOM xpcom("Synchronization (" __FILE__ ")");
   362     if (xpcom.failed())
   363         return 1;
   365     int rv = 0;
   367     if (NS_FAILED(Sanity()))
   368         rv = 1;
   369     if (NS_FAILED(MutexContention()))
   370         rv = 1;
   371     if (NS_FAILED(MonitorContention()))
   372         rv = 1;
   373     if (NS_FAILED(MonitorContention2()))
   374         rv = 1;
   375     if (NS_FAILED(MonitorSyncSanity()))
   376         rv = 1;
   377     if (NS_FAILED(CondVarSanity()))
   378         rv = 1;
   379     if (NS_FAILED(AutoLock()))
   380         rv = 1;
   381     if (NS_FAILED(AutoUnlock()))
   382         rv = 1;
   383     if (NS_FAILED(AutoMonitor()))
   384         rv = 1;
   386     return rv;
   387 }

mercurial