1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 
5 /*
6  * RWLock rank tests
7  */
8 
9 #include "nspr.h"
10 #include "plgetopt.h"
11 
12 static int _debug_on;
13 static PRRWLock *rwlock0;
14 static PRRWLock *rwlock1;
15 static PRRWLock *rwlock2;
16 
rwtest(void * args)17 static void rwtest(void *args)
18 {
19     PR_RWLock_Rlock(rwlock1);
20     PR_RWLock_Unlock(rwlock1);
21 
22     PR_RWLock_Rlock(rwlock1);
23     PR_RWLock_Unlock(rwlock1);
24 
25     /* Test correct lock rank. */
26     PR_RWLock_Rlock(rwlock1);
27     PR_RWLock_Rlock(rwlock2);
28     PR_RWLock_Unlock(rwlock2);
29     PR_RWLock_Unlock(rwlock1);
30 
31     PR_RWLock_Rlock(rwlock1);
32     PR_RWLock_Rlock(rwlock2);
33     PR_RWLock_Unlock(rwlock1);
34     PR_RWLock_Unlock(rwlock2);
35 
36     PR_RWLock_Rlock(rwlock1);
37     PR_RWLock_Rlock(rwlock0);
38     PR_RWLock_Rlock(rwlock2);
39     PR_RWLock_Unlock(rwlock2);
40     PR_RWLock_Unlock(rwlock0);
41     PR_RWLock_Unlock(rwlock1);
42 
43 #if 0
44     /* Test incorrect lock rank. */
45     PR_RWLock_Rlock(rwlock2);
46     PR_RWLock_Rlock(rwlock1);
47     PR_RWLock_Unlock(rwlock1);
48     PR_RWLock_Unlock(rwlock2);
49 
50     PR_RWLock_Rlock(rwlock2);
51     PR_RWLock_Rlock(rwlock0);
52     PR_RWLock_Rlock(rwlock1);
53     PR_RWLock_Unlock(rwlock1);
54     PR_RWLock_Unlock(rwlock0);
55     PR_RWLock_Unlock(rwlock2);
56 #endif
57 }
58 
main(int argc,char ** argv)59 int main(int argc, char **argv)
60 {
61     PRStatus rc;
62     PRThread *thread;
63     PLOptStatus os;
64     PLOptState *opt = PL_CreateOptState(argc, argv, "d");
65 
66     while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
67         if (PL_OPT_BAD == os) {
68             continue;
69         }
70         switch (opt->option) {
71             case 'd':  /* debug mode */
72                 _debug_on = 1;
73                 break;
74             default:
75                 break;
76         }
77     }
78     PL_DestroyOptState(opt);
79 
80     rwlock0 = PR_NewRWLock(PR_RWLOCK_RANK_NONE, "Lock 0");
81     if (rwlock0 == NULL) {
82         fprintf(stderr, "PR_NewRWLock failed - error %d\n",
83                 (int)PR_GetError());
84         return 1;
85     }
86     rwlock1 = PR_NewRWLock(1, "Lock 1");
87     if (rwlock1 == NULL) {
88         fprintf(stderr, "PR_NewRWLock failed - error %d\n",
89                 (int)PR_GetError());
90         return 1;
91     }
92     rwlock2 = PR_NewRWLock(2, "Lock 2");
93     if (rwlock2 == NULL) {
94         fprintf(stderr, "PR_NewRWLock failed - error %d\n",
95                 (int)PR_GetError());
96         return 1;
97     }
98 
99     thread = PR_CreateThread(PR_USER_THREAD, rwtest, NULL, PR_PRIORITY_NORMAL,
100                              PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
101     if (thread == NULL) {
102         fprintf(stderr, "PR_CreateThread failed - error %d\n",
103                 (int)PR_GetError());
104         PR_ProcessExit(2);
105     }
106     if (_debug_on) {
107         printf("%s: created thread = %p\n", argv[0], thread);
108     }
109 
110     rc = PR_JoinThread(thread);
111     PR_ASSERT(rc == PR_SUCCESS);
112 
113     PR_DestroyRWLock(rwlock0);
114     rwlock0 = NULL;
115     PR_DestroyRWLock(rwlock1);
116     rwlock1 = NULL;
117     PR_DestroyRWLock(rwlock2);
118     rwlock2 = NULL;
119 
120     printf("PASS\n");
121     return 0;
122 }
123