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

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. /*
  34.  * Locking and queue management primatives
  35.  *
  36.  */
  37. #include "seccomon.h"
  38. #include "prlock.h"
  39. #include "prmon.h"
  40. #include "secmod.h"
  41. #include "secmodi.h"
  42. #include "prlong.h"
  43. #define ISREADING 1
  44. #define ISWRITING 2
  45. #define WANTWRITE 4
  46. #define ISLOCKED 3
  47. /*
  48.  * create a new lock for a Module List
  49.  */
  50. SECMODListLock *SECMOD_NewListLock() {
  51.     SECMODListLock *modLock;
  52.     modLock = (SECMODListLock*)PORT_Alloc(sizeof(SECMODListLock));
  53. #ifdef PKCS11_USE_THREADS
  54.     modLock->mutex = NULL;
  55.     modLock->monitor = PR_NewMonitor();
  56. #else
  57.     modLock->mutex = NULL;
  58.     modLock->monitor = NULL;
  59. #endif
  60.     modLock->state = 0;
  61.     modLock->count = 0;
  62.     return modLock;
  63. }
  64. /*
  65.  * destroy the lock
  66.  */
  67. void SECMOD_DestroyListLock(SECMODListLock *lock) {
  68.     PK11_USE_THREADS(PR_DestroyMonitor(lock->monitor);)
  69.     PORT_Free(lock);
  70. }
  71. /*
  72.  * Lock the List for Read: NOTE: this assumes the reading isn't so common
  73.  * the writing will be starved.
  74.  */
  75. void SECMOD_GetReadLock(SECMODListLock *modLock) {
  76. #ifdef PKCS11_USE_THREADS
  77.     if (modLock == NULL) return;
  78.     PR_EnterMonitor(modLock->monitor);
  79.     while (modLock->state & ISWRITING) {
  80. PR_Wait(modLock->monitor,PR_INTERVAL_NO_TIMEOUT); /* wait until woken up */
  81.     }
  82.     modLock->state |= ISREADING;
  83.     modLock->count++;
  84.     PR_ExitMonitor(modLock->monitor);
  85. #endif
  86. }
  87. /*
  88.  * Release the Read lock
  89.  */
  90. void SECMOD_ReleaseReadLock(SECMODListLock *modLock) {
  91. #ifdef PKCS11_USE_THREADS
  92.     if (modLock == NULL) return;
  93.     PR_EnterMonitor(modLock->monitor);
  94.     modLock->count--;
  95.     if (modLock->count == 0) {
  96. modLock->state &= ~ISREADING;
  97. if (modLock->state & WANTWRITE) {
  98.     PR_Notify(modLock->monitor);  /* only one writer at a time */
  99. }
  100.     }
  101.     PR_ExitMonitor(modLock->monitor);
  102. #endif
  103. }
  104. /*
  105.  * lock the list for Write
  106.  */
  107. void SECMOD_GetWriteLock(SECMODListLock *modLock) {
  108. #ifdef PKCS11_USE_THREADS
  109.     if (modLock == NULL) return;
  110.     PR_EnterMonitor(modLock->monitor);
  111.     while (modLock->state & ISLOCKED) {
  112. modLock->state |= WANTWRITE;
  113. PR_Wait(modLock->monitor,PR_INTERVAL_NO_TIMEOUT); /* wait until woken up */
  114.     }
  115.     modLock->state = ISWRITING;
  116.     PR_ExitMonitor(modLock->monitor);
  117. #endif
  118. }
  119. /*
  120.  * Release the Write Lock: NOTE, this code is pretty inefficient if you have
  121.  * lots of write collisions.
  122.  */
  123. void SECMOD_ReleaseWriteLock(SECMODListLock *modLock) {
  124. #ifdef PKCS11_USE_THREADS
  125.     if (modLock == NULL) return;
  126.     PR_EnterMonitor(modLock->monitor);
  127.     modLock->state = 0;
  128.     PR_NotifyAll(modLock->monitor); /* enable all the readers */
  129.     PR_ExitMonitor(modLock->monitor);
  130. #endif
  131. }
  132. /*
  133.  * must Hold the Write lock
  134.  */
  135. void
  136. SECMOD_RemoveList(SECMODModuleList **parent, SECMODModuleList *child) {
  137.     *parent = child->next;
  138.     child->next = NULL;
  139. }
  140. /*
  141.  * if lock is not specified, it must already be held
  142.  */
  143. void
  144. SECMOD_AddList(SECMODModuleList *parent, SECMODModuleList *child, 
  145. SECMODListLock *lock) {
  146.     if (lock) { SECMOD_GetWriteLock(lock); }
  147.     child->next = parent->next;
  148.     parent->next = child;
  149.    if (lock) { SECMOD_ReleaseWriteLock(lock); }
  150. }