Back to index

lightning-sunbird  0.9+nobinonly
mutex.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the Netscape security libraries.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 1994-2000
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 #ifdef DEBUG
00038 static const char CVS_ID[] = "@(#) $RCSfile: mutex.c,v $ $Revision: 1.7 $ $Date: 2005/08/25 20:08:26 $";
00039 #endif /* DEBUG */
00040 
00041 /*
00042  * mutex.c
00043  *
00044  * This file implements a mutual-exclusion locking facility for Modules
00045  * using the NSS Cryptoki Framework.
00046  */
00047 
00048 #ifndef CK_T
00049 #include "ck.h"
00050 #endif /* CK_T */
00051 
00052 /*
00053  * NSSCKFWMutex
00054  *
00055  *  NSSCKFWMutex_Destroy
00056  *  NSSCKFWMutex_Lock
00057  *  NSSCKFWMutex_Unlock
00058  *
00059  *  nssCKFWMutex_Create
00060  *  nssCKFWMutex_Destroy
00061  *  nssCKFWMutex_Lock
00062  *  nssCKFWMutex_Unlock
00063  *
00064  *  -- debugging versions only --
00065  *  nssCKFWMutex_verifyPointer
00066  *
00067  */
00068 
00069 struct NSSCKFWMutexStr {
00070   PRLock *lock;
00071 };
00072 
00073 #ifdef DEBUG
00074 /*
00075  * But first, the pointer-tracking stuff.
00076  *
00077  * NOTE: the pointer-tracking support in NSS/base currently relies
00078  * upon NSPR's CallOnce support.  That, however, relies upon NSPR's
00079  * locking, which is tied into the runtime.  We need a pointer-tracker
00080  * implementation that uses the locks supplied through C_Initialize.
00081  * That support, however, can be filled in later.  So for now, I'll
00082  * just do this routines as no-ops.
00083  */
00084 
00085 static CK_RV
00086 mutex_add_pointer
00087 (
00088   const NSSCKFWMutex *fwMutex
00089 )
00090 {
00091   return CKR_OK;
00092 }
00093 
00094 static CK_RV
00095 mutex_remove_pointer
00096 (
00097   const NSSCKFWMutex *fwMutex
00098 )
00099 {
00100   return CKR_OK;
00101 }
00102 
00103 NSS_IMPLEMENT CK_RV
00104 nssCKFWMutex_verifyPointer
00105 (
00106   const NSSCKFWMutex *fwMutex
00107 )
00108 {
00109   return CKR_OK;
00110 }
00111 
00112 #endif /* DEBUG */
00113 
00114 static CK_RV
00115 mutex_noop
00116 (
00117   CK_VOID_PTR pMutex
00118 )
00119 {
00120   return CKR_OK;
00121 }
00122 
00123 /*
00124  * nssCKFWMutex_Create
00125  *
00126  */
00127 NSS_EXTERN NSSCKFWMutex *
00128 nssCKFWMutex_Create
00129 (
00130   CK_C_INITIALIZE_ARGS_PTR pInitArgs,
00131   CryptokiLockingState LockingState,
00132   NSSArena *arena,
00133   CK_RV *pError
00134 )
00135 {
00136   NSSCKFWMutex *mutex;
00137   
00138   mutex = nss_ZNEW(arena, NSSCKFWMutex);
00139   if( (NSSCKFWMutex *)NULL == mutex ) {
00140     *pError = CKR_HOST_MEMORY;
00141     return (NSSCKFWMutex *)NULL;
00142   }
00143   *pError = CKR_OK;
00144   mutex->lock = NULL;
00145   if (LockingState == MultiThreaded) {
00146     mutex->lock = PR_NewLock();
00147     if (!mutex->lock) {
00148       *pError = CKR_HOST_MEMORY; /* we couldn't get the resource */
00149     }
00150   }
00151     
00152   if( CKR_OK != *pError ) {
00153     (void)nss_ZFreeIf(mutex);
00154     return (NSSCKFWMutex *)NULL;
00155   }
00156 
00157 #ifdef DEBUG
00158   *pError = mutex_add_pointer(mutex);
00159   if( CKR_OK != *pError ) {
00160     if (mutex->lock) {
00161       PR_DestroyLock(mutex->lock);
00162     }
00163     (void)nss_ZFreeIf(mutex);
00164     return (NSSCKFWMutex *)NULL;
00165   }
00166 #endif /* DEBUG */
00167 
00168   return mutex;
00169 }  
00170 
00171 /*
00172  * nssCKFWMutex_Destroy
00173  *
00174  */
00175 NSS_EXTERN CK_RV
00176 nssCKFWMutex_Destroy
00177 (
00178   NSSCKFWMutex *mutex
00179 )
00180 {
00181   CK_RV rv = CKR_OK;
00182 
00183 #ifdef NSSDEBUG
00184   rv = nssCKFWMutex_verifyPointer(mutex);
00185   if( CKR_OK != rv ) {
00186     return rv;
00187   }
00188 #endif /* NSSDEBUG */
00189  
00190   if (mutex->lock) {
00191     PR_DestroyLock(mutex->lock);
00192   } 
00193 
00194 #ifdef DEBUG
00195   (void)mutex_remove_pointer(mutex);
00196 #endif /* DEBUG */
00197 
00198   (void)nss_ZFreeIf(mutex);
00199   return rv;
00200 }
00201 
00202 /*
00203  * nssCKFWMutex_Lock
00204  *
00205  */
00206 NSS_EXTERN CK_RV
00207 nssCKFWMutex_Lock
00208 (
00209   NSSCKFWMutex *mutex
00210 )
00211 {
00212 #ifdef NSSDEBUG
00213   CK_RV rv = nssCKFWMutex_verifyPointer(mutex);
00214   if( CKR_OK != rv ) {
00215     return rv;
00216   }
00217 #endif /* NSSDEBUG */
00218   if (mutex->lock) {
00219     PR_Lock(mutex->lock);
00220   }
00221   
00222   return CKR_OK;
00223 }
00224 
00225 /*
00226  * nssCKFWMutex_Unlock
00227  *
00228  */
00229 NSS_EXTERN CK_RV
00230 nssCKFWMutex_Unlock
00231 (
00232   NSSCKFWMutex *mutex
00233 )
00234 {
00235   PRStatus nrv;
00236 #ifdef NSSDEBUG
00237   CK_RV rv = nssCKFWMutex_verifyPointer(mutex);
00238 
00239   if( CKR_OK != rv ) {
00240     return rv;
00241   }
00242 #endif /* NSSDEBUG */
00243 
00244   if (!mutex->lock) 
00245     return CKR_OK;
00246 
00247   nrv =  PR_Unlock(mutex->lock);
00248 
00249   /* if unlock fails, either we have a programming error, or we have
00250    * some sort of hardware failure... in either case return CKR_DEVICE_ERROR.
00251    */
00252   return nrv == PR_SUCCESS ? CKR_OK : CKR_DEVICE_ERROR;
00253 }
00254 
00255 /*
00256  * NSSCKFWMutex_Destroy
00257  *
00258  */
00259 NSS_EXTERN CK_RV
00260 NSSCKFWMutex_Destroy
00261 (
00262   NSSCKFWMutex *mutex
00263 )
00264 {
00265 #ifdef DEBUG
00266   CK_RV rv = nssCKFWMutex_verifyPointer(mutex);
00267   if( CKR_OK != rv ) {
00268     return rv;
00269   }
00270 #endif /* DEBUG */
00271   
00272   return nssCKFWMutex_Destroy(mutex);
00273 }
00274 
00275 /*
00276  * NSSCKFWMutex_Lock
00277  *
00278  */
00279 NSS_EXTERN CK_RV
00280 NSSCKFWMutex_Lock
00281 (
00282   NSSCKFWMutex *mutex
00283 )
00284 {
00285 #ifdef DEBUG
00286   CK_RV rv = nssCKFWMutex_verifyPointer(mutex);
00287   if( CKR_OK != rv ) {
00288     return rv;
00289   }
00290 #endif /* DEBUG */
00291   
00292   return nssCKFWMutex_Lock(mutex);
00293 }
00294 
00295 /*
00296  * NSSCKFWMutex_Unlock
00297  *
00298  */
00299 NSS_EXTERN CK_RV
00300 NSSCKFWMutex_Unlock
00301 (
00302   NSSCKFWMutex *mutex
00303 )
00304 {
00305 #ifdef DEBUG
00306   CK_RV rv = nssCKFWMutex_verifyPointer(mutex);
00307   if( CKR_OK != rv ) {
00308     return rv;
00309   }
00310 #endif /* DEBUG */
00311 
00312   return nssCKFWMutex_Unlock(mutex);
00313 }
00314