michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* michael@0: * mutex.c michael@0: * michael@0: * This file implements a mutual-exclusion locking facility for Modules michael@0: * using the NSS Cryptoki Framework. michael@0: */ michael@0: michael@0: #ifndef CK_T michael@0: #include "ck.h" michael@0: #endif /* CK_T */ michael@0: michael@0: /* michael@0: * NSSCKFWMutex michael@0: * michael@0: * NSSCKFWMutex_Destroy michael@0: * NSSCKFWMutex_Lock michael@0: * NSSCKFWMutex_Unlock michael@0: * michael@0: * nssCKFWMutex_Create michael@0: * nssCKFWMutex_Destroy michael@0: * nssCKFWMutex_Lock michael@0: * nssCKFWMutex_Unlock michael@0: * michael@0: * -- debugging versions only -- michael@0: * nssCKFWMutex_verifyPointer michael@0: * michael@0: */ michael@0: michael@0: struct NSSCKFWMutexStr { michael@0: PRLock *lock; michael@0: }; michael@0: michael@0: #ifdef DEBUG michael@0: /* michael@0: * But first, the pointer-tracking stuff. michael@0: * michael@0: * NOTE: the pointer-tracking support in NSS/base currently relies michael@0: * upon NSPR's CallOnce support. That, however, relies upon NSPR's michael@0: * locking, which is tied into the runtime. We need a pointer-tracker michael@0: * implementation that uses the locks supplied through C_Initialize. michael@0: * That support, however, can be filled in later. So for now, I'll michael@0: * just do this routines as no-ops. michael@0: */ michael@0: michael@0: static CK_RV michael@0: mutex_add_pointer michael@0: ( michael@0: const NSSCKFWMutex *fwMutex michael@0: ) michael@0: { michael@0: return CKR_OK; michael@0: } michael@0: michael@0: static CK_RV michael@0: mutex_remove_pointer michael@0: ( michael@0: const NSSCKFWMutex *fwMutex michael@0: ) michael@0: { michael@0: return CKR_OK; michael@0: } michael@0: michael@0: NSS_IMPLEMENT CK_RV michael@0: nssCKFWMutex_verifyPointer michael@0: ( michael@0: const NSSCKFWMutex *fwMutex michael@0: ) michael@0: { michael@0: return CKR_OK; michael@0: } michael@0: michael@0: #endif /* DEBUG */ michael@0: michael@0: /* michael@0: * nssCKFWMutex_Create michael@0: * michael@0: */ michael@0: NSS_EXTERN NSSCKFWMutex * michael@0: nssCKFWMutex_Create michael@0: ( michael@0: CK_C_INITIALIZE_ARGS_PTR pInitArgs, michael@0: CryptokiLockingState LockingState, michael@0: NSSArena *arena, michael@0: CK_RV *pError michael@0: ) michael@0: { michael@0: NSSCKFWMutex *mutex; michael@0: michael@0: mutex = nss_ZNEW(arena, NSSCKFWMutex); michael@0: if (!mutex) { michael@0: *pError = CKR_HOST_MEMORY; michael@0: return (NSSCKFWMutex *)NULL; michael@0: } michael@0: *pError = CKR_OK; michael@0: mutex->lock = NULL; michael@0: if (LockingState == MultiThreaded) { michael@0: mutex->lock = PR_NewLock(); michael@0: if (!mutex->lock) { michael@0: *pError = CKR_HOST_MEMORY; /* we couldn't get the resource */ michael@0: } michael@0: } michael@0: michael@0: if( CKR_OK != *pError ) { michael@0: (void)nss_ZFreeIf(mutex); michael@0: return (NSSCKFWMutex *)NULL; michael@0: } michael@0: michael@0: #ifdef DEBUG michael@0: *pError = mutex_add_pointer(mutex); michael@0: if( CKR_OK != *pError ) { michael@0: if (mutex->lock) { michael@0: PR_DestroyLock(mutex->lock); michael@0: } michael@0: (void)nss_ZFreeIf(mutex); michael@0: return (NSSCKFWMutex *)NULL; michael@0: } michael@0: #endif /* DEBUG */ michael@0: michael@0: return mutex; michael@0: } michael@0: michael@0: /* michael@0: * nssCKFWMutex_Destroy michael@0: * michael@0: */ michael@0: NSS_EXTERN CK_RV michael@0: nssCKFWMutex_Destroy michael@0: ( michael@0: NSSCKFWMutex *mutex michael@0: ) michael@0: { michael@0: CK_RV rv = CKR_OK; michael@0: michael@0: #ifdef NSSDEBUG michael@0: rv = nssCKFWMutex_verifyPointer(mutex); michael@0: if( CKR_OK != rv ) { michael@0: return rv; michael@0: } michael@0: #endif /* NSSDEBUG */ michael@0: michael@0: if (mutex->lock) { michael@0: PR_DestroyLock(mutex->lock); michael@0: } michael@0: michael@0: #ifdef DEBUG michael@0: (void)mutex_remove_pointer(mutex); michael@0: #endif /* DEBUG */ michael@0: michael@0: (void)nss_ZFreeIf(mutex); michael@0: return rv; michael@0: } michael@0: michael@0: /* michael@0: * nssCKFWMutex_Lock michael@0: * michael@0: */ michael@0: NSS_EXTERN CK_RV michael@0: nssCKFWMutex_Lock michael@0: ( michael@0: NSSCKFWMutex *mutex michael@0: ) michael@0: { michael@0: #ifdef NSSDEBUG michael@0: CK_RV rv = nssCKFWMutex_verifyPointer(mutex); michael@0: if( CKR_OK != rv ) { michael@0: return rv; michael@0: } michael@0: #endif /* NSSDEBUG */ michael@0: if (mutex->lock) { michael@0: PR_Lock(mutex->lock); michael@0: } michael@0: michael@0: return CKR_OK; michael@0: } michael@0: michael@0: /* michael@0: * nssCKFWMutex_Unlock michael@0: * michael@0: */ michael@0: NSS_EXTERN CK_RV michael@0: nssCKFWMutex_Unlock michael@0: ( michael@0: NSSCKFWMutex *mutex michael@0: ) michael@0: { michael@0: PRStatus nrv; michael@0: #ifdef NSSDEBUG michael@0: CK_RV rv = nssCKFWMutex_verifyPointer(mutex); michael@0: michael@0: if( CKR_OK != rv ) { michael@0: return rv; michael@0: } michael@0: #endif /* NSSDEBUG */ michael@0: michael@0: if (!mutex->lock) michael@0: return CKR_OK; michael@0: michael@0: nrv = PR_Unlock(mutex->lock); michael@0: michael@0: /* if unlock fails, either we have a programming error, or we have michael@0: * some sort of hardware failure... in either case return CKR_DEVICE_ERROR. michael@0: */ michael@0: return nrv == PR_SUCCESS ? CKR_OK : CKR_DEVICE_ERROR; michael@0: } michael@0: michael@0: /* michael@0: * NSSCKFWMutex_Destroy michael@0: * michael@0: */ michael@0: NSS_EXTERN CK_RV michael@0: NSSCKFWMutex_Destroy michael@0: ( michael@0: NSSCKFWMutex *mutex michael@0: ) michael@0: { michael@0: #ifdef DEBUG michael@0: CK_RV rv = nssCKFWMutex_verifyPointer(mutex); michael@0: if( CKR_OK != rv ) { michael@0: return rv; michael@0: } michael@0: #endif /* DEBUG */ michael@0: michael@0: return nssCKFWMutex_Destroy(mutex); michael@0: } michael@0: michael@0: /* michael@0: * NSSCKFWMutex_Lock michael@0: * michael@0: */ michael@0: NSS_EXTERN CK_RV michael@0: NSSCKFWMutex_Lock michael@0: ( michael@0: NSSCKFWMutex *mutex michael@0: ) michael@0: { michael@0: #ifdef DEBUG michael@0: CK_RV rv = nssCKFWMutex_verifyPointer(mutex); michael@0: if( CKR_OK != rv ) { michael@0: return rv; michael@0: } michael@0: #endif /* DEBUG */ michael@0: michael@0: return nssCKFWMutex_Lock(mutex); michael@0: } michael@0: michael@0: /* michael@0: * NSSCKFWMutex_Unlock michael@0: * michael@0: */ michael@0: NSS_EXTERN CK_RV michael@0: NSSCKFWMutex_Unlock michael@0: ( michael@0: NSSCKFWMutex *mutex michael@0: ) michael@0: { michael@0: #ifdef DEBUG michael@0: CK_RV rv = nssCKFWMutex_verifyPointer(mutex); michael@0: if( CKR_OK != rv ) { michael@0: return rv; michael@0: } michael@0: #endif /* DEBUG */ michael@0: michael@0: return nssCKFWMutex_Unlock(mutex); michael@0: } michael@0: