Back to index

lightning-sunbird  0.9+nobinonly
tpd.c
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is the Netscape Portable Runtime (NSPR).
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998-2000
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 /*
00039 ** File:        tpd.c
00040 ** Description: Exercising the thread private data bailywick.
00041 */
00042 
00043 #include "prmem.h"
00044 #include "prinit.h"
00045 #include "prlog.h"
00046 #include "prprf.h"
00047 #include "prthread.h"
00048 #include "prtypes.h"
00049 
00050 #if defined(XP_MAC)
00051 #include "pprio.h"
00052 #else
00053 #include "private/pprio.h"
00054 #endif
00055 
00056 #include "plgetopt.h"
00057 
00058 static PRUintn key[128];
00059 static PRIntn debug = 0;
00060 static PRBool failed = PR_FALSE;
00061 static PRBool should = PR_TRUE;
00062 static PRBool did = PR_TRUE;
00063 static PRFileDesc *fout = NULL;
00064 
00065 static void PrintProgress(PRIntn line)
00066 {
00067     failed = failed || (should && !did);
00068     failed = failed || (!should && did);
00069     if (debug > 0)
00070     {
00071 #if defined(WIN16)
00072         printf(
00073             "@ line %d destructor should%s have been called and was%s\n",
00074             line, ((should) ? "" : " NOT"), ((did) ? "" : " NOT"));
00075 #else    
00076         PR_fprintf(
00077             fout, "@ line %d destructor should%s have been called and was%s\n",
00078             line, ((should) ? "" : " NOT"), ((did) ? "" : " NOT"));
00079 #endif
00080     }
00081 }  /* PrintProgress */
00082 
00083 static void MyAssert(const char *expr, const char *file, PRIntn line)
00084 {
00085     if (debug > 0)
00086         (void)PR_fprintf(fout, "'%s' in file: %s: %d\n", expr, file, line);
00087 }  /* MyAssert */
00088 
00089 #define MY_ASSERT(_expr) \
00090     ((_expr)?((void)0):MyAssert(# _expr,__FILE__,__LINE__))
00091 
00092 
00093 static void PR_CALLBACK Destructor(void *data)
00094 {
00095     MY_ASSERT(NULL != data);
00096     if (should) did = PR_TRUE;
00097     else failed = PR_TRUE;
00098     /*
00099      * We don't actually free the storage since it's actually allocated
00100      * on the stack. Normally, this would not be the case and this is
00101      * the opportunity to free whatever.
00102     PR_Free(data);
00103      */
00104 }  /* Destructor */
00105 
00106 static void PR_CALLBACK Thread(void *null)
00107 {
00108     void *pd;
00109     PRStatus rv;
00110     PRUintn keys;
00111     char *key_string[] = {
00112         "Key #0", "Key #1", "Key #2", "Key #3",
00113         "Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8"};
00114     
00115     did = should = PR_FALSE;
00116     for (keys = 0; keys < 8; ++keys)
00117     {
00118         pd = PR_GetThreadPrivate(key[keys]);
00119         MY_ASSERT(NULL == pd);
00120     }
00121     PrintProgress(__LINE__);
00122 
00123     did = should = PR_FALSE;
00124     for (keys = 0; keys < 4; ++keys)
00125     {
00126         rv = PR_SetThreadPrivate(key[keys], key_string[keys]);
00127         MY_ASSERT(PR_SUCCESS == rv);
00128     }
00129     PrintProgress(__LINE__);
00130 
00131     did = should = PR_FALSE;
00132     for (keys = 4; keys < 8; ++keys)
00133     {
00134         rv = PR_SetThreadPrivate(key[keys], key_string[keys]);
00135         MY_ASSERT(PR_FAILURE == rv);
00136     }
00137     PrintProgress(__LINE__);
00138     
00139     did = PR_FALSE; should = PR_TRUE;
00140     for (keys = 0; keys < 4; ++keys)
00141     {
00142         rv = PR_SetThreadPrivate(key[keys], key_string[keys]);
00143         MY_ASSERT(PR_SUCCESS == rv);
00144     }
00145     PrintProgress(__LINE__);
00146 
00147     did = PR_FALSE; should = PR_TRUE;
00148     for (keys = 0; keys < 4; ++keys)
00149     {
00150         rv = PR_SetThreadPrivate(key[keys], NULL);
00151         MY_ASSERT(PR_SUCCESS == rv);
00152     }
00153     PrintProgress(__LINE__);
00154 
00155     did = should = PR_FALSE;
00156     for (keys = 0; keys < 4; ++keys)
00157     {
00158         rv = PR_SetThreadPrivate(key[keys], NULL);
00159         MY_ASSERT(PR_SUCCESS == rv);
00160     }
00161     PrintProgress(__LINE__);
00162 
00163     did = should = PR_FALSE;
00164     for (keys = 8; keys < 127; ++keys)
00165     {
00166         rv = PR_SetThreadPrivate(key[keys], "EXTENSION");
00167         MY_ASSERT(PR_SUCCESS == rv);
00168     }
00169     PrintProgress(__LINE__);
00170 
00171     did = PR_FALSE; should = PR_TRUE;
00172     for (keys = 8; keys < 127; ++keys)
00173     {
00174         rv = PR_SetThreadPrivate(key[keys], NULL);
00175         MY_ASSERT(PR_SUCCESS == rv);
00176     }
00177     PrintProgress(__LINE__);
00178 
00179     did = should = PR_FALSE;
00180     for (keys = 8; keys < 127; ++keys)
00181     {
00182         rv = PR_SetThreadPrivate(key[keys], NULL);
00183         MY_ASSERT(PR_SUCCESS == rv);
00184     }
00185 
00186     /* put in keys and leave them there for thread exit */
00187     did = should = PR_FALSE;
00188     for (keys = 0; keys < 4; ++keys)
00189     {
00190         rv = PR_SetThreadPrivate(key[keys], key_string[keys]);
00191         MY_ASSERT(PR_SUCCESS == rv);
00192     }
00193     PrintProgress(__LINE__);
00194     did = PR_FALSE; should = PR_TRUE;
00195 
00196 }  /* Thread */
00197 
00198 static PRIntn PR_CALLBACK Tpd(PRIntn argc, char **argv)
00199 {
00200     void *pd;
00201     PRStatus rv;
00202     PRUintn keys;
00203     PRThread *thread;
00204     char *key_string[] = {
00205         "Key #0", "Key #1", "Key #2", "Key #3",
00206         "Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8"};
00207     
00208     fout = PR_STDOUT;
00209 
00210     did = should = PR_FALSE;
00211     for (keys = 0; keys < 4; ++keys)
00212     {
00213         rv = PR_NewThreadPrivateIndex(&key[keys], Destructor);
00214         MY_ASSERT(PR_SUCCESS == rv);
00215     }
00216     PrintProgress(__LINE__);
00217 
00218     did = should = PR_FALSE;
00219     for (keys = 0; keys < 8; ++keys)
00220     {
00221         pd = PR_GetThreadPrivate(key[keys]);
00222         MY_ASSERT(NULL == pd);
00223     }
00224     PrintProgress(__LINE__);
00225 
00226     did = should = PR_FALSE;
00227     for (keys = 0; keys < 4; ++keys)
00228     {
00229         rv = PR_SetThreadPrivate(key[keys], key_string[keys]);
00230         MY_ASSERT(PR_SUCCESS == rv);
00231     }
00232     PrintProgress(__LINE__);
00233 
00234     for (keys = 4; keys < 8; ++keys)
00235               key[keys] = 4096;           /* set to invalid value */
00236     did = should = PR_FALSE;
00237     for (keys = 4; keys < 8; ++keys)
00238     {
00239         rv = PR_SetThreadPrivate(key[keys], key_string[keys]);
00240         MY_ASSERT(PR_FAILURE == rv);
00241     }
00242     PrintProgress(__LINE__);
00243     
00244     did = PR_FALSE; should = PR_TRUE;
00245     for (keys = 0; keys < 4; ++keys)
00246     {
00247         rv = PR_SetThreadPrivate(key[keys], key_string[keys]);
00248         MY_ASSERT(PR_SUCCESS == rv);
00249     }
00250     PrintProgress(__LINE__);
00251 
00252     did = PR_FALSE; should = PR_TRUE;
00253     for (keys = 0; keys < 4; ++keys)
00254     {
00255         rv = PR_SetThreadPrivate(key[keys], NULL);
00256         MY_ASSERT(PR_SUCCESS == rv);
00257     }
00258     PrintProgress(__LINE__);
00259 
00260     did = should = PR_FALSE;
00261     for (keys = 0; keys < 4; ++keys)
00262     {
00263         rv = PR_SetThreadPrivate(key[keys], NULL);
00264         MY_ASSERT(PR_SUCCESS == rv);
00265     }
00266     PrintProgress(__LINE__);
00267 
00268     did = should = PR_FALSE;
00269     for (keys = 8; keys < 127; ++keys)
00270     {
00271         rv = PR_NewThreadPrivateIndex(&key[keys], Destructor);
00272         MY_ASSERT(PR_SUCCESS == rv);
00273         rv = PR_SetThreadPrivate(key[keys], "EXTENSION");
00274         MY_ASSERT(PR_SUCCESS == rv);
00275     }
00276     PrintProgress(__LINE__);
00277 
00278     did = PR_FALSE; should = PR_TRUE;
00279     for (keys = 8; keys < 127; ++keys)
00280     {
00281         rv = PR_SetThreadPrivate(key[keys], NULL);
00282         MY_ASSERT(PR_SUCCESS == rv);
00283     }
00284     PrintProgress(__LINE__);
00285 
00286     did = should = PR_FALSE;
00287     for (keys = 8; keys < 127; ++keys)
00288     {
00289         rv = PR_SetThreadPrivate(key[keys], NULL);
00290         MY_ASSERT(PR_SUCCESS == rv);
00291     }
00292 
00293     thread = PR_CreateThread(
00294         PR_USER_THREAD, Thread, NULL, PR_PRIORITY_NORMAL,
00295         PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
00296 
00297     (void)PR_JoinThread(thread);
00298 
00299     PrintProgress(__LINE__);
00300 
00301 #if defined(WIN16)
00302     printf(
00303         "%s\n",((PR_TRUE == failed) ? "FAILED" : "PASSED"));
00304 #else
00305     (void)PR_fprintf(
00306         fout, "%s\n",((PR_TRUE == failed) ? "FAILED" : "PASSED"));
00307 #endif    
00308 
00309     return 0;
00310 
00311 }  /* Tpd */
00312 
00313 PRIntn main(PRIntn argc, char *argv[])
00314 {
00315        PLOptStatus os;
00316        PLOptState *opt = PL_CreateOptState(argc, argv, "dl:r:");
00317        while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
00318     {
00319               if (PL_OPT_BAD == os) continue;
00320         switch (opt->option)
00321         {
00322         case 'd':  /* debug mode */
00323                      debug = PR_TRUE;
00324             break;
00325          default:
00326             break;
00327         }
00328     }
00329        PL_DestroyOptState(opt);
00330     PR_STDIO_INIT();
00331     return PR_Initialize(Tpd, argc, argv, 0);
00332 }  /* main */
00333 
00334 /* tpd.c */