mutex.c (4567B)
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 * mutex.c 7 * 8 * This file implements a mutual-exclusion locking facility for Modules 9 * using the NSS Cryptoki Framework. 10 */ 11 12 #ifndef CK_T 13 #include "ck.h" 14 #endif /* CK_T */ 15 16 /* 17 * NSSCKFWMutex 18 * 19 * NSSCKFWMutex_Destroy 20 * NSSCKFWMutex_Lock 21 * NSSCKFWMutex_Unlock 22 * 23 * nssCKFWMutex_Create 24 * nssCKFWMutex_Destroy 25 * nssCKFWMutex_Lock 26 * nssCKFWMutex_Unlock 27 * 28 * -- debugging versions only -- 29 * nssCKFWMutex_verifyPointer 30 * 31 */ 32 33 struct NSSCKFWMutexStr { 34 PRLock *lock; 35 }; 36 37 #ifdef DEBUG 38 /* 39 * But first, the pointer-tracking stuff. 40 * 41 * NOTE: the pointer-tracking support in NSS/base currently relies 42 * upon NSPR's CallOnce support. That, however, relies upon NSPR's 43 * locking, which is tied into the runtime. We need a pointer-tracker 44 * implementation that uses the locks supplied through C_Initialize. 45 * That support, however, can be filled in later. So for now, I'll 46 * just do this routines as no-ops. 47 */ 48 49 static CK_RV 50 mutex_add_pointer( 51 const NSSCKFWMutex *fwMutex) 52 { 53 return CKR_OK; 54 } 55 56 static CK_RV 57 mutex_remove_pointer( 58 const NSSCKFWMutex *fwMutex) 59 { 60 return CKR_OK; 61 } 62 63 NSS_IMPLEMENT CK_RV 64 nssCKFWMutex_verifyPointer( 65 const NSSCKFWMutex *fwMutex) 66 { 67 return CKR_OK; 68 } 69 70 #endif /* DEBUG */ 71 72 /* 73 * nssCKFWMutex_Create 74 * 75 */ 76 NSS_EXTERN NSSCKFWMutex * 77 nssCKFWMutex_Create( 78 CK_C_INITIALIZE_ARGS_PTR pInitArgs, 79 CryptokiLockingState LockingState, 80 NSSArena *arena, 81 CK_RV *pError) 82 { 83 NSSCKFWMutex *mutex; 84 85 mutex = nss_ZNEW(arena, NSSCKFWMutex); 86 if (!mutex) { 87 *pError = CKR_HOST_MEMORY; 88 return (NSSCKFWMutex *)NULL; 89 } 90 *pError = CKR_OK; 91 mutex->lock = NULL; 92 if (LockingState == MultiThreaded) { 93 mutex->lock = PR_NewLock(); 94 if (!mutex->lock) { 95 *pError = CKR_HOST_MEMORY; /* we couldn't get the resource */ 96 } 97 } 98 99 if (CKR_OK != *pError) { 100 (void)nss_ZFreeIf(mutex); 101 return (NSSCKFWMutex *)NULL; 102 } 103 104 #ifdef DEBUG 105 *pError = mutex_add_pointer(mutex); 106 if (CKR_OK != *pError) { 107 if (mutex->lock) { 108 PR_DestroyLock(mutex->lock); 109 } 110 (void)nss_ZFreeIf(mutex); 111 return (NSSCKFWMutex *)NULL; 112 } 113 #endif /* DEBUG */ 114 115 return mutex; 116 } 117 118 /* 119 * nssCKFWMutex_Destroy 120 * 121 */ 122 NSS_EXTERN CK_RV 123 nssCKFWMutex_Destroy( 124 NSSCKFWMutex *mutex) 125 { 126 CK_RV rv = CKR_OK; 127 128 #ifdef NSSDEBUG 129 rv = nssCKFWMutex_verifyPointer(mutex); 130 if (CKR_OK != rv) { 131 return rv; 132 } 133 #endif /* NSSDEBUG */ 134 135 if (mutex->lock) { 136 PR_DestroyLock(mutex->lock); 137 } 138 139 #ifdef DEBUG 140 (void)mutex_remove_pointer(mutex); 141 #endif /* DEBUG */ 142 143 (void)nss_ZFreeIf(mutex); 144 return rv; 145 } 146 147 /* 148 * nssCKFWMutex_Lock 149 * 150 */ 151 NSS_EXTERN CK_RV 152 nssCKFWMutex_Lock( 153 NSSCKFWMutex *mutex) 154 { 155 #ifdef NSSDEBUG 156 CK_RV rv = nssCKFWMutex_verifyPointer(mutex); 157 if (CKR_OK != rv) { 158 return rv; 159 } 160 #endif /* NSSDEBUG */ 161 if (mutex->lock) { 162 PR_Lock(mutex->lock); 163 } 164 165 return CKR_OK; 166 } 167 168 /* 169 * nssCKFWMutex_Unlock 170 * 171 */ 172 NSS_EXTERN CK_RV 173 nssCKFWMutex_Unlock( 174 NSSCKFWMutex *mutex) 175 { 176 PRStatus nrv; 177 #ifdef NSSDEBUG 178 CK_RV rv = nssCKFWMutex_verifyPointer(mutex); 179 180 if (CKR_OK != rv) { 181 return rv; 182 } 183 #endif /* NSSDEBUG */ 184 185 if (!mutex->lock) 186 return CKR_OK; 187 188 nrv = PR_Unlock(mutex->lock); 189 190 /* if unlock fails, either we have a programming error, or we have 191 * some sort of hardware failure... in either case return CKR_DEVICE_ERROR. 192 */ 193 return nrv == PR_SUCCESS ? CKR_OK : CKR_DEVICE_ERROR; 194 } 195 196 /* 197 * NSSCKFWMutex_Destroy 198 * 199 */ 200 NSS_EXTERN CK_RV 201 NSSCKFWMutex_Destroy( 202 NSSCKFWMutex *mutex) 203 { 204 #ifdef DEBUG 205 CK_RV rv = nssCKFWMutex_verifyPointer(mutex); 206 if (CKR_OK != rv) { 207 return rv; 208 } 209 #endif /* DEBUG */ 210 211 return nssCKFWMutex_Destroy(mutex); 212 } 213 214 /* 215 * NSSCKFWMutex_Lock 216 * 217 */ 218 NSS_EXTERN CK_RV 219 NSSCKFWMutex_Lock( 220 NSSCKFWMutex *mutex) 221 { 222 #ifdef DEBUG 223 CK_RV rv = nssCKFWMutex_verifyPointer(mutex); 224 if (CKR_OK != rv) { 225 return rv; 226 } 227 #endif /* DEBUG */ 228 229 return nssCKFWMutex_Lock(mutex); 230 } 231 232 /* 233 * NSSCKFWMutex_Unlock 234 * 235 */ 236 NSS_EXTERN CK_RV 237 NSSCKFWMutex_Unlock( 238 NSSCKFWMutex *mutex) 239 { 240 #ifdef DEBUG 241 CK_RV rv = nssCKFWMutex_verifyPointer(mutex); 242 if (CKR_OK != rv) { 243 return rv; 244 } 245 #endif /* DEBUG */ 246 247 return nssCKFWMutex_Unlock(mutex); 248 }