test_rwlock.c (6396B)
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 * test_rwlock.c 6 * 7 */ 8 9 #include "testutil.h" 10 #include "testutil_nss.h" 11 12 static PKIX_PL_RWLock *rwlock = NULL, *rwlock2 = NULL, *rwlock3 = NULL; 13 static PRThread *thread = NULL, *thread2 = NULL, *thread3 = NULL; 14 static void *plContext = NULL; 15 16 static void 17 reader(void) 18 { 19 PKIX_Error *errorResult; 20 21 errorResult = PKIX_PL_AcquireReaderLock(rwlock, NULL); 22 if (errorResult) 23 testError("PKIX_PL_AcquireReaderLock failed"); 24 25 (void)printf("\t[Thread #1 Read Lock #1.]\n"); 26 (void)printf("\t[Thread #1 Sleeplng for 1 seconds.]\n"); 27 PR_Sleep(PR_SecondsToInterval(1)); 28 PKIX_PL_ReleaseReaderLock(rwlock, NULL); 29 if (errorResult) 30 testError("PKIX_PL_ReleaseReaderLock failed"); 31 (void)printf("\t[Thread #1 Read UNLock #1.]\n"); 32 } 33 34 static void 35 writer(void) 36 { 37 PKIX_Error *errorResult; 38 /* This thread should stick here until lock 1 is released */ 39 PKIX_PL_AcquireWriterLock(rwlock, NULL); 40 if (errorResult) 41 testError("PKIX_PL_AcquireWriterLock failed"); 42 43 (void)printf("\t[Thread #2 Write Lock #1.]\n"); 44 45 PKIX_PL_AcquireWriterLock(rwlock2, NULL); 46 if (errorResult) 47 testError("PKIX_PL_AcquireWriterLock failed"); 48 (void)printf("\t[Thread #2 Write Lock #2.]\n"); 49 50 (void)printf("\t[Thread #2 Sleeplng for 1 seconds.]\n"); 51 PR_Sleep(PR_SecondsToInterval(1)); 52 53 PKIX_PL_ReleaseWriterLock(rwlock2, NULL); 54 if (errorResult) 55 testError("PKIX_PL_ReleaseWriterLock failed"); 56 (void)printf("\t[Thread #2 Write UNLock #2.]\n"); 57 58 (void)printf("\t[Thread #2 Sleeplng for 1 seconds.]\n"); 59 PR_Sleep(PR_SecondsToInterval(1)); 60 61 PKIX_PL_ReleaseWriterLock(rwlock, NULL); 62 if (errorResult) 63 testError("PKIX_PL_ReleaseWriterLock failed"); 64 (void)printf("\t[Thread #2 Write UNLock #1.]\n"); 65 66 PR_JoinThread(thread3); 67 } 68 69 static void 70 reader2(void) 71 { 72 PKIX_Error *errorResult; 73 /* Reader 2 should yield here until the writer is done */ 74 75 PKIX_PL_AcquireReaderLock(rwlock2, NULL); 76 if (errorResult) 77 testError("PKIX_PL_AcquireReaderLock failed"); 78 79 (void)printf("\t[Thread #3 Read Lock #2.]\n"); 80 81 PKIX_PL_AcquireReaderLock(rwlock3, NULL); 82 if (errorResult) 83 testError("PKIX_PL_AcquireReaderLock failed"); 84 (void)printf("\t[Thread #3 Read Lock #3.]\n"); 85 86 (void)printf("\t[Thread #3 Sleeplng for 1 seconds.]\n"); 87 PR_Sleep(PR_SecondsToInterval(1)); 88 89 PKIX_PL_ReleaseReaderLock(rwlock3, NULL); 90 if (errorResult) 91 testError("PKIX_PL_ReleaseReaderLock failed"); 92 (void)printf("\t[Thread #3 Read UNLock #3.]\n"); 93 94 (void)printf("\t[Thread #3 Sleeplng for 1 seconds.]\n"); 95 PR_Sleep(PR_SecondsToInterval(1)); 96 97 PKIX_PL_ReleaseReaderLock(rwlock2, NULL); 98 if (errorResult) 99 testError("PKIX_PL_ReleaseReaderLock failed"); 100 (void)printf("\t[Thread #3 Read UNLock #2.]\n"); 101 } 102 103 int 104 test_rwlock() 105 { 106 PKIX_PL_String *outputString = NULL; 107 PKIX_UInt32 j = 0; 108 PKIX_Boolean bool; 109 PKIX_UInt32 actualMinorVersion; 110 111 PKIX_TEST_STD_VARS(); 112 startTests("RWLocks"); 113 114 PKIX_TEST_EXPECT_NO_ERROR( 115 PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext)); 116 117 (void)printf("Attempting to create new rwlock...\n"); 118 119 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_RWLock_Create(&rwlock, plContext)); 120 121 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_RWLock_Create(&rwlock2, plContext)); 122 123 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_RWLock_Create(&rwlock3, plContext)); 124 125 /* Test toString functionality */ 126 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)rwlock, &outputString, plContext)); 127 128 (void)printf("Testing RWLock toString: %s\n", 129 PKIX_String2ASCII(outputString)); 130 131 PKIX_TEST_DECREF_BC(outputString); 132 133 /* Call Equals on two different objects */ 134 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals((PKIX_PL_Object *)rwlock, 135 (PKIX_PL_Object *)rwlock2, 136 &bool, 137 plContext)); 138 139 (void)printf("Testing RWLock Equals: %d (should be 0)\n", bool); 140 141 if (bool != 0) 142 testError("Error in RWLock_Equals"); 143 144 /* Call Equals on two equal objects */ 145 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals((PKIX_PL_Object *)rwlock, 146 (PKIX_PL_Object *)rwlock, &bool, plContext)); 147 148 (void)printf("Testing RWLock Equals: %d (should be 1)\n", bool); 149 if (bool != 1) 150 testError("Error in RWLock_Equals"); 151 152 subTest("Multi-Thread Read/Write Lock Testing"); 153 154 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_AcquireReaderLock(rwlock, plContext)); 155 (void)printf("\t[Main Thread Read Lock #1.]\n"); 156 157 thread = PR_CreateThread(PR_USER_THREAD, 158 reader, 159 NULL, 160 PR_PRIORITY_NORMAL, 161 PR_LOCAL_THREAD, 162 PR_JOINABLE_THREAD, 163 0); 164 165 thread2 = PR_CreateThread(PR_USER_THREAD, 166 writer, 167 NULL, 168 PR_PRIORITY_NORMAL, 169 PR_LOCAL_THREAD, 170 PR_JOINABLE_THREAD, 171 0); 172 173 thread3 = PR_CreateThread(PR_USER_THREAD, 174 reader2, 175 NULL, 176 PR_PRIORITY_NORMAL, 177 PR_LOCAL_THREAD, 178 PR_JOINABLE_THREAD, 179 0); 180 181 PR_JoinThread(thread); 182 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_ReleaseReaderLock(rwlock, plContext)); 183 (void)printf("\t[Main Thread Read Unlock #1.]\n"); 184 185 PR_JoinThread(thread2); 186 187 cleanup: 188 189 /* Test destructor */ 190 subTest("Testing destructor..."); 191 PKIX_TEST_DECREF_AC(rwlock); 192 PKIX_TEST_DECREF_AC(rwlock2); 193 PKIX_TEST_DECREF_AC(rwlock3); 194 195 pkixTestTempResult = PKIX_Shutdown(plContext); 196 if (pkixTestTempResult) 197 pkixTestErrorResult = pkixTestTempResult; 198 199 PKIX_TEST_RETURN(); 200 201 endTests("RWLocks"); 202 203 return (0); 204 }