mutex.c
上传用户:lyxiangda
上传日期:2007-01-12
资源大小:3042k
文件大小:7k
源码类别:

CA认证

开发平台:

WINDOWS

  1. /* 
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is the Netscape security libraries.
  13.  * 
  14.  * The Initial Developer of the Original Code is Netscape
  15.  * Communications Corporation.  Portions created by Netscape are 
  16.  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All
  17.  * Rights Reserved.
  18.  * 
  19.  * Contributor(s):
  20.  * 
  21.  * Alternatively, the contents of this file may be used under the
  22.  * terms of the GNU General Public License Version 2 or later (the
  23.  * "GPL"), in which case the provisions of the GPL are applicable 
  24.  * instead of those above.  If you wish to allow use of your 
  25.  * version of this file only under the terms of the GPL and not to
  26.  * allow others to use your version of this file under the MPL,
  27.  * indicate your decision by deleting the provisions above and
  28.  * replace them with the notice and other provisions required by
  29.  * the GPL.  If you do not delete the provisions above, a recipient
  30.  * may use your version of this file under either the MPL or the
  31.  * GPL.
  32.  */
  33. #ifdef DEBUG
  34. static const char CVS_ID[] = "@(#) $RCSfile: mutex.c,v $ $Revision: 1.1 $ $Date: 2000/03/31 19:43:26 $ $Name: NSS_3_1_1_RTM $";
  35. #endif /* DEBUG */
  36. /*
  37.  * mutex.c
  38.  *
  39.  * This file implements a mutual-exclusion locking facility for Modules
  40.  * using the NSS Cryptoki Framework.
  41.  */
  42. #ifndef CK_T
  43. #include "ck.h"
  44. #endif /* CK_T */
  45. /*
  46.  * NSSCKFWMutex
  47.  *
  48.  *  NSSCKFWMutex_Destroy
  49.  *  NSSCKFWMutex_Lock
  50.  *  NSSCKFWMutex_Unlock
  51.  *
  52.  *  nssCKFWMutex_Create
  53.  *  nssCKFWMutex_Destroy
  54.  *  nssCKFWMutex_Lock
  55.  *  nssCKFWMutex_Unlock
  56.  *
  57.  *  -- debugging versions only --
  58.  *  nssCKFWMutex_verifyPointer
  59.  *
  60.  */
  61. struct NSSCKFWMutexStr {
  62.   CK_VOID_PTR etc;
  63.   CK_DESTROYMUTEX Destroy;
  64.   CK_LOCKMUTEX Lock;
  65.   CK_UNLOCKMUTEX Unlock;
  66. };
  67. #ifdef DEBUG
  68. /*
  69.  * But first, the pointer-tracking stuff.
  70.  *
  71.  * NOTE: the pointer-tracking support in NSS/base currently relies
  72.  * upon NSPR's CallOnce support.  That, however, relies upon NSPR's
  73.  * locking, which is tied into the runtime.  We need a pointer-tracker
  74.  * implementation that uses the locks supplied through C_Initialize.
  75.  * That support, however, can be filled in later.  So for now, I'll
  76.  * just do this routines as no-ops.
  77.  */
  78. static CK_RV
  79. mutex_add_pointer
  80. (
  81.   const NSSCKFWMutex *fwMutex
  82. )
  83. {
  84.   return CKR_OK;
  85. }
  86. static CK_RV
  87. mutex_remove_pointer
  88. (
  89.   const NSSCKFWMutex *fwMutex
  90. )
  91. {
  92.   return CKR_OK;
  93. }
  94. NSS_IMPLEMENT CK_RV
  95. nssCKFWMutex_verifyPointer
  96. (
  97.   const NSSCKFWMutex *fwMutex
  98. )
  99. {
  100.   return CKR_OK;
  101. }
  102. #endif /* DEBUG */
  103. static CK_RV
  104. mutex_noop
  105. (
  106.   CK_VOID_PTR pMutex
  107. )
  108. {
  109.   return CKR_OK;
  110. }
  111. /*
  112.  * nssCKFWMutex_Create
  113.  *
  114.  */
  115. NSS_EXTERN NSSCKFWMutex *
  116. nssCKFWMutex_Create
  117. (
  118.   CK_C_INITIALIZE_ARGS_PTR pInitArgs,
  119.   NSSArena *arena,
  120.   CK_RV *pError
  121. )
  122. {
  123.   NSSCKFWMutex *mutex;
  124.   CK_ULONG count = (CK_ULONG)0;
  125.   CK_BBOOL os_ok = CK_FALSE;
  126.   CK_VOID_PTR pMutex = (CK_VOID_PTR)NULL;
  127.   if( (CK_C_INITIALIZE_ARGS_PTR)NULL != pInitArgs ) {
  128.     if( (CK_CREATEMUTEX )NULL != pInitArgs->CreateMutex  ) count++;
  129.     if( (CK_DESTROYMUTEX)NULL != pInitArgs->DestroyMutex ) count++;
  130.     if( (CK_LOCKMUTEX   )NULL != pInitArgs->LockMutex    ) count++;
  131.     if( (CK_UNLOCKMUTEX )NULL != pInitArgs->UnlockMutex  ) count++;
  132.     os_ok = (pInitArgs->flags & CKF_OS_LOCKING_OK) ? CK_TRUE : CK_FALSE;
  133.     if( (0 != count) && (4 != count) ) {
  134.       *pError = CKR_ARGUMENTS_BAD;
  135.       return (NSSCKFWMutex *)NULL;
  136.     }
  137.   }
  138.   if( (0 == count) && (CK_TRUE == os_ok) ) {
  139.     /*
  140.      * This is case #2 in the description of C_Initialize:
  141.      * The library will be called in a multithreaded way, but
  142.      * no routines were specified: os locking calls should be
  143.      * used.  Unfortunately, this can be hard.. like, I think
  144.      * I may have to dynamically look up the entry points in
  145.      * the instance of NSPR already going in the application.
  146.      *
  147.      * I know that *we* always specify routines, so this only
  148.      * comes up if someone is using NSS to create their own
  149.      * PCKS#11 modules for other products.  Oh, heck, I'll 
  150.      * worry about this then.
  151.      */
  152.     *pError = CKR_CANT_LOCK;
  153.     return (NSSCKFWMutex *)NULL;
  154.   }
  155.   mutex = nss_ZNEW(arena, NSSCKFWMutex);
  156.   if( (NSSCKFWMutex *)NULL == mutex ) {
  157.     *pError = CKR_HOST_MEMORY;
  158.     return (NSSCKFWMutex *)NULL;
  159.   }
  160.   if( 0 == count ) {
  161.     /*
  162.      * With the above test out of the way, we know this is case
  163.      * #1 in the description of C_Initialize: this library will
  164.      * not be called in a multithreaded way.  I'll just return
  165.      * an object with noop calls.
  166.      */
  167.     mutex->Destroy = (CK_DESTROYMUTEX)mutex_noop;
  168.     mutex->Lock    = (CK_LOCKMUTEX   )mutex_noop;
  169.     mutex->Unlock  = (CK_UNLOCKMUTEX )mutex_noop;
  170.   } else {
  171.     /*
  172.      * We know that we're in either case #3 or #4 in the description
  173.      * of C_Initialize.  Case #3 says we should use the specified
  174.      * functions, case #4 cays we can use either the specified ones
  175.      * or the OS ones.  I'll use the specified ones.
  176.      */
  177.     mutex->Destroy = pInitArgs->DestroyMutex;
  178.     mutex->Lock    = pInitArgs->LockMutex;
  179.     mutex->Unlock  = pInitArgs->UnlockMutex;
  180.     
  181.     *pError = pInitArgs->CreateMutex(&mutex->etc);
  182.     if( CKR_OK != *pError ) {
  183.       (void)nss_ZFreeIf(mutex);
  184.       return (NSSCKFWMutex *)NULL;
  185.     }
  186.   }
  187. #ifdef DEBUG
  188.   *pError = mutex_add_pointer(mutex);
  189.   if( CKR_OK != *pError ) {
  190.     (void)nss_ZFreeIf(mutex);
  191.     return (NSSCKFWMutex *)NULL;
  192.   }
  193. #endif /* DEBUG */
  194.   return mutex;
  195. }  
  196. /*
  197.  * nssCKFWMutex_Destroy
  198.  *
  199.  */
  200. NSS_EXTERN CK_RV
  201. nssCKFWMutex_Destroy
  202. (
  203.   NSSCKFWMutex *mutex
  204. )
  205. {
  206.   CK_RV rv = CKR_OK;
  207. #ifdef NSSDEBUG
  208.   rv = nssCKFWMutex_verifyPointer(mutex);
  209.   if( CKR_OK != rv ) {
  210.     return rv;
  211.   }
  212. #endif /* NSSDEBUG */
  213.   
  214.   rv = mutex->Destroy(mutex->etc);
  215. #ifdef DEBUG
  216.   (void)mutex_remove_pointer(mutex);
  217. #endif /* DEBUG */
  218.   (void)nss_ZFreeIf(mutex);
  219.   return rv;
  220. }
  221. /*
  222.  * nssCKFWMutex_Lock
  223.  *
  224.  */
  225. NSS_EXTERN CK_RV
  226. nssCKFWMutex_Lock
  227. (
  228.   NSSCKFWMutex *mutex
  229. )
  230. {
  231. #ifdef NSSDEBUG
  232.   CK_RV rv = nssCKFWMutex_verifyPointer(mutex);
  233.   if( CKR_OK != rv ) {
  234.     return rv;
  235.   }
  236. #endif /* NSSDEBUG */
  237.   
  238.   return mutex->Lock(mutex->etc);
  239. }
  240. /*
  241.  * nssCKFWMutex_Unlock
  242.  *
  243.  */
  244. NSS_EXTERN CK_RV
  245. nssCKFWMutex_Unlock
  246. (
  247.   NSSCKFWMutex *mutex
  248. )
  249. {
  250. #ifdef NSSDEBUG
  251.   CK_RV rv = nssCKFWMutex_verifyPointer(mutex);
  252.   if( CKR_OK != rv ) {
  253.     return rv;
  254.   }
  255. #endif /* NSSDEBUG */
  256.   return mutex->Unlock(mutex->etc);
  257. }
  258. /*
  259.  * NSSCKFWMutex_Destroy
  260.  *
  261.  */
  262. NSS_EXTERN CK_RV
  263. NSSCKFWMutex_Destroy
  264. (
  265.   NSSCKFWMutex *mutex
  266. )
  267. {
  268. #ifdef DEBUG
  269.   CK_RV rv = nssCKFWMutex_verifyPointer(mutex);
  270.   if( CKR_OK != rv ) {
  271.     return rv;
  272.   }
  273. #endif /* DEBUG */
  274.   
  275.   return nssCKFWMutex_Destroy(mutex);
  276. }
  277. /*
  278.  * NSSCKFWMutex_Lock
  279.  *
  280.  */
  281. NSS_EXTERN CK_RV
  282. NSSCKFWMutex_Lock
  283. (
  284.   NSSCKFWMutex *mutex
  285. )
  286. {
  287. #ifdef DEBUG
  288.   CK_RV rv = nssCKFWMutex_verifyPointer(mutex);
  289.   if( CKR_OK != rv ) {
  290.     return rv;
  291.   }
  292. #endif /* DEBUG */
  293.   
  294.   return nssCKFWMutex_Lock(mutex);
  295. }
  296. /*
  297.  * NSSCKFWMutex_Unlock
  298.  *
  299.  */
  300. NSS_EXTERN CK_RV
  301. NSSCKFWMutex_Unlock
  302. (
  303.   NSSCKFWMutex *mutex
  304. )
  305. {
  306. #ifdef DEBUG
  307.   CK_RV rv = nssCKFWMutex_verifyPointer(mutex);
  308.   if( CKR_OK != rv ) {
  309.     return rv;
  310.   }
  311. #endif /* DEBUG */
  312.   return nssCKFWMutex_Unlock(mutex);
  313. }