Source code

Revision control

Copy as Markdown

Other Tools

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