nsprpub/pr/src/cplus/tests/tpd.cpp

Fri, 16 Jan 2015 04:50:19 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 04:50:19 +0100
branch
TOR_BUG_9701
changeset 13
44a2da4a2ab2
permissions
-rw-r--r--

Replace accessor implementation with direct member state manipulation, by
request https://trac.torproject.org/projects/tor/ticket/9701#comment:32

     1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     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 /*
     7 ** File:        tpd.cpp
     8 ** Description: Exercising the thread private data bailywick.
     9 */
    11 #include "prlog.h"
    12 #include "prprf.h"
    13 #include "rcthread.h"
    15 #include <string.h>
    17 #include "plgetopt.h"
    19 /*
    20 ** class MyThread
    21 */
    22 class MyThread: public RCThread
    23 {
    24 public:
    25     MyThread();
    27 private:
    28     ~MyThread();
    29     void RootFunction();
    30 };  /* MyThread */
    32 /*
    33 ** class MyPrivateData
    34 */
    35 class MyPrivateData: public RCThreadPrivateData
    36 {
    37 public:
    38     virtual ~MyPrivateData();
    40     MyPrivateData();
    41     MyPrivateData(char*);
    42     MyPrivateData(const MyPrivateData&);
    44     void Release();
    46 private:
    47     char *string;
    48 };  /* MyPrivateData */
    50 static PRUintn key[128];
    51 static PRIntn debug = 0;
    52 static PRBool failed = PR_FALSE;
    53 static PRBool should = PR_TRUE;
    54 static PRBool did = PR_TRUE;
    55 static PRFileDesc *fout = NULL;
    57 static void PrintProgress(PRIntn line)
    58 {
    59     failed = failed || (should && !did);
    60     failed = failed || (!should && did);
    61     if (debug > 0)
    62     {
    63         PR_fprintf(
    64             fout, "@ line %d destructor should %shave been called and was%s\n",
    65             line, ((should) ? "" : "NOT "), ((did) ? "" : " NOT"));
    66     }
    67 }  /* PrintProgress */
    69 static void MyAssert(const char *expr, const char *file, PRIntn line)
    70 {
    71     if (debug > 0)
    72         (void)PR_fprintf(fout, "'%s' in file: %s: %d\n", expr, file, line);
    73 }  /* MyAssert */
    75 #define MY_ASSERT(_expr) \
    76     ((_expr)?((void)0):MyAssert(# _expr,__FILE__,__LINE__))
    78 int main(PRIntn argc, char *argv[])
    79 {
    80     PRStatus rv;
    81     PRUintn keys;
    82     MyThread *thread;
    83     const RCThreadPrivateData *pd;
    84     PLOptStatus os;
    85     PLOptState *opt = PL_CreateOptState(argc, argv, "d");
    86     RCThread *primordial = RCThread::WrapPrimordialThread();
    87     while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
    88     {
    89         if (PL_OPT_BAD == os) continue;
    90         switch (opt->option)
    91         {
    92         case 'd':  /* debug mode */
    93             debug = PR_TRUE;
    94             break;
    95          default:
    96             break;
    97         }
    98     }
    99     PL_DestroyOptState(opt);
   101     fout = PR_STDOUT;
   103     MyPrivateData extension = MyPrivateData("EXTENSION");
   104     MyPrivateData key_string[] = {
   105         "Key #0", "Key #1", "Key #2", "Key #3",
   106         "Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8"};
   109     did = should = PR_FALSE;
   110     for (keys = 0; keys < 4; ++keys)
   111     {
   112         rv = RCThread::NewPrivateIndex(&key[keys]);
   113         key[keys + 4] = key[keys] + 4;
   114         MY_ASSERT(PR_SUCCESS == rv);
   115     }
   116     PrintProgress(__LINE__);
   118     /* the first four should be bu null, the last four undefined and null */
   119     did = should = PR_FALSE;
   120     for (keys = 0; keys < 8; ++keys)
   121     {
   122         pd = RCThread::GetPrivateData(key[keys]);
   123         MY_ASSERT(NULL == pd);
   124     }
   125     PrintProgress(__LINE__);
   127     /* initially set private data for new keys */
   128     did = should = PR_FALSE;
   129     for (keys = 0; keys < 4; ++keys)
   130     {
   131         rv = RCThread::SetPrivateData(key[keys], &key_string[keys]);
   132         MY_ASSERT(PR_SUCCESS == rv);
   133     }
   134     PrintProgress(__LINE__);
   136     /* re-assign the private data, albeit the same content */    
   137     did = PR_FALSE; should = PR_TRUE;
   138     for (keys = 0; keys < 4; ++keys)
   139     {
   140         pd = RCThread::GetPrivateData(key[keys]);
   141         PR_ASSERT(NULL != pd);
   142         rv = RCThread::SetPrivateData(key[keys], &key_string[keys]);
   143         MY_ASSERT(PR_SUCCESS == rv);
   144     }
   145     PrintProgress(__LINE__);
   147     /* set private to <empty> */
   148     did = PR_FALSE; should = PR_TRUE;
   149     for (keys = 0; keys < 4; ++keys)
   150     {
   151         rv = RCThread::SetPrivateData(key[keys]);
   152         MY_ASSERT(PR_SUCCESS == rv);
   153     }
   154     PrintProgress(__LINE__);
   156     /* should all be null now */
   157     did = should = PR_FALSE;
   158     for (keys = 0; keys < 4; ++keys)
   159     {
   160         pd = RCThread::GetPrivateData(key[keys]);
   161         PR_ASSERT(NULL == pd);
   162     }
   163     PrintProgress(__LINE__);
   165     /* allocate another batch of keys and assign data to them */
   166     did = should = PR_FALSE;
   167     for (keys = 8; keys < 127; ++keys)
   168     {
   169         rv = RCThread::NewPrivateIndex(&key[keys]);
   170         MY_ASSERT(PR_SUCCESS == rv);
   171         rv = RCThread::SetPrivateData(key[keys], &extension);
   172         MY_ASSERT(PR_SUCCESS == rv);
   173     }
   174     PrintProgress(__LINE__);
   176     /* set all the extended slots to <empty> */
   177     did = PR_FALSE; should = PR_TRUE;
   178     for (keys = 8; keys < 127; ++keys)
   179     {
   180         rv = RCThread::SetPrivateData(key[keys]);
   181         MY_ASSERT(PR_SUCCESS == rv);
   182     }
   183     PrintProgress(__LINE__);
   185     /* set all the extended slots to <empty> again (noop) */
   186     did = should = PR_FALSE;
   187     for (keys = 8; keys < 127; ++keys)
   188     {
   189         rv = RCThread::SetPrivateData(key[keys]);
   190         MY_ASSERT(PR_SUCCESS == rv);
   191     }
   193     if (debug) PR_fprintf(fout, "Creating thread\n");
   194     thread = new MyThread();
   195     if (debug) PR_fprintf(fout, "Starting thread\n");
   196     thread->Start();
   197     if (debug) PR_fprintf(fout, "Joining thread\n");
   198     (void)thread->Join();
   199     if (debug) PR_fprintf(fout, "Joined thread\n");
   201     failed |= (PR_FAILURE == RCPrimordialThread::Cleanup());
   203     (void)PR_fprintf(
   204         fout, "%s\n",((PR_TRUE == failed) ? "FAILED" : "PASSED"));
   206     return (failed) ? 1 : 0;
   208 }  /* main */
   210 /*
   211 ** class MyPrivateData
   212 */
   213 MyPrivateData::~MyPrivateData()
   214 {
   215     PR_fprintf(
   216         fout, "MyPrivateData::~MyPrivateData[%s]\n",
   217         (NULL != string) ? string : "NULL");
   218 }  /* MyPrivateData::~MyPrivateData */
   220 MyPrivateData::MyPrivateData(): RCThreadPrivateData()
   221 {
   222     PR_fprintf(fout, "MyPrivateData::MyPrivateData()\n");
   223     string = NULL;
   224 }  /* MyPrivateData::MyPrivateData */
   226 MyPrivateData::MyPrivateData(char* data): RCThreadPrivateData()
   227 {
   228     PR_fprintf(fout, "MyPrivateData::MyPrivateData(char* data)\n");
   229     string = data;
   230 }  /* MyPrivateData:: MyPrivateData */
   232 MyPrivateData::MyPrivateData(const MyPrivateData& him): RCThreadPrivateData(him)
   233 {
   234     PR_fprintf(fout, "MyPrivateData::MyPrivateData(const MyPrivateData& him)\n");
   235     string = him.string;
   236 }  /* MyPrivateData:: MyPrivateData */
   238 void MyPrivateData::Release()
   239 {
   240     if (should) did = PR_TRUE;
   241     else failed = PR_TRUE;
   242 }  /* MyPrivateData::operator= */
   244 /*
   245 ** class MyThread
   246 */
   247 MyThread::~MyThread() { }
   248 MyThread::MyThread(): RCThread(RCThread::global, RCThread::joinable) { }
   251 void MyThread::RootFunction()
   252 {
   253     PRStatus rv;
   254     PRUintn keys;
   255     const RCThreadPrivateData *pd;
   257     MyPrivateData extension = MyPrivateData("EXTENSION");
   258     MyPrivateData key_string[] = {
   259         "Key #0", "Key #1", "Key #2", "Key #3",
   260         "Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8"};
   262     did = should = PR_FALSE;
   263     for (keys = 0; keys < 8; ++keys)
   264     {
   265         pd = GetPrivateData(key[keys]);
   266         MY_ASSERT(NULL == pd);
   267     }
   268     PrintProgress(__LINE__);
   270     did = should = PR_FALSE;
   271     for (keys = 0; keys < 4; ++keys)
   272     {
   273         rv = SetPrivateData(keys, &key_string[keys]);
   274         MY_ASSERT(PR_SUCCESS == rv);
   275     }
   276     PrintProgress(__LINE__);
   278 #if !defined(DEBUG)
   279     did = should = PR_FALSE;
   280     for (keys = 4; keys < 8; ++keys)
   281     {
   282         rv = SetPrivateData(keys, &key_string[keys]);
   283         MY_ASSERT(PR_FAILURE == rv);
   284     }
   285     PrintProgress(__LINE__);
   286 #endif
   288     did = PR_FALSE; should = PR_TRUE;
   289     for (keys = 0; keys < 4; ++keys)
   290     {
   291         rv = SetPrivateData(key[keys], &key_string[keys]);
   292         MY_ASSERT(PR_SUCCESS == rv);
   293     }
   294     PrintProgress(__LINE__);
   296     did = PR_FALSE; should = PR_TRUE;
   297     for (keys = 0; keys < 4; ++keys)
   298     {
   299         rv = SetPrivateData(key[keys]);
   300         MY_ASSERT(PR_SUCCESS == rv);
   301     }
   302     PrintProgress(__LINE__);
   304     did = should = PR_FALSE;
   305     for (keys = 0; keys < 4; ++keys)
   306     {
   307         rv = SetPrivateData(key[keys]);
   308         MY_ASSERT(PR_SUCCESS == rv);
   309     }
   310     PrintProgress(__LINE__);
   312     did = should = PR_FALSE;
   313     for (keys = 8; keys < 127; ++keys)
   314     {
   315         rv = SetPrivateData(key[keys], &extension);
   316         MY_ASSERT(PR_SUCCESS == rv);
   317     }
   318     PrintProgress(__LINE__);
   320     did = PR_FALSE; should = PR_TRUE;
   321     for (keys = 8; keys < 127; ++keys)
   322     {
   323         rv = SetPrivateData(key[keys]);
   324         MY_ASSERT(PR_SUCCESS == rv);
   325     }
   326     PrintProgress(__LINE__);
   328     did = should = PR_FALSE;
   329     for (keys = 8; keys < 127; ++keys)
   330     {
   331         rv = SetPrivateData(key[keys]);
   332         MY_ASSERT(PR_SUCCESS == rv);
   333     }
   334 }  /* MyThread::RootFunction */
   336 /* tpd.c */

mercurial