Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

180 lines
4.2 KiB

  1. /*****************************************************************/
  2. /** Microsoft Windows for Workgroups **/
  3. /** Copyright (C) Microsoft Corp., 1993-1994 **/
  4. /*****************************************************************/
  5. /* npcrit.c -- Implementation of critical section classes.
  6. *
  7. * History:
  8. * 11/01/93 gregj Created
  9. */
  10. #include "npcommon.h"
  11. #include <npcrit.h>
  12. #include <npassert.h>
  13. /*
  14. * Very simple interlock routines, used to stop race conditions when
  15. * initializing and de-initializing critical sections. Do NOT use
  16. * these for anything other than infrequent extremely short-term locks,
  17. * since WaitForInterlock contains a spin loop with a millisecond delay!
  18. */
  19. BYTE InterlockedSet(volatile BYTE *pByte)
  20. {
  21. BYTE bRet;
  22. _asm {
  23. mov edi, pByte
  24. mov al, 1
  25. xchg [edi], al /* store non-zero value, get what was there before */
  26. mov bRet, al
  27. }
  28. return bRet;
  29. }
  30. void WaitForInterlock(volatile BYTE *pByte)
  31. {
  32. for (;;) {
  33. BYTE bAlreadyOwned = InterlockedSet(pByte); /* attempt to grab the interlock */
  34. if (!bAlreadyOwned) /* is someone else in there? */
  35. break; /* nope, we now own it */
  36. Sleep(1); /* yield to whomever owns it, then try again */
  37. }
  38. }
  39. void ReleaseInterlock(volatile BYTE *pByte)
  40. {
  41. *pByte = 0; /* clear the interlock to release others */
  42. }
  43. #if 0
  44. // Remove CRITSEC code but keep for a while before deleting.
  45. /*******************************************************************
  46. NAME: CRITSEC::Init
  47. SYNOPSIS: Initializes a global critical section object
  48. ENTRY: pszName - name for the critical section
  49. EXIT: No return value
  50. NOTES: Currently pszName is not used; it will be used
  51. for named mutexes later.
  52. HISTORY:
  53. gregj 11/01/93 Created
  54. ********************************************************************/
  55. void CRITSEC::Init(char *pszName)
  56. {
  57. WaitForInterlock(&_bInterlock);
  58. if (!_fInitialized) {
  59. ::InitializeCriticalSection(&_critsec);
  60. #ifdef DEBUG
  61. _wClaimCount = 0;
  62. #endif
  63. _fInitialized = 1;
  64. }
  65. ReleaseInterlock(&_bInterlock);
  66. _cClients++;
  67. }
  68. /*******************************************************************
  69. NAME: CRITSEC::Term
  70. SYNOPSIS: Cleans up resources allocated for a critical section
  71. ENTRY: No parameters
  72. EXIT: No return value
  73. NOTES: This function should be callled at process attach.
  74. It will take care of making sure it only deletes
  75. the critical section when the last process using
  76. it calls Term().
  77. HISTORY:
  78. gregj 11/01/93 Created
  79. ********************************************************************/
  80. void CRITSEC::Term()
  81. {
  82. WaitForInterlock(&_bInterlock);
  83. BOOL fShouldCleanUp = (--_cClients == 0);
  84. if (fShouldCleanUp) {
  85. ::DeleteCriticalSection(&_critsec);
  86. _fInitialized = 0;
  87. }
  88. ReleaseInterlock(&_bInterlock);
  89. }
  90. #ifdef DEBUG /* in retail, these are inline */
  91. /*******************************************************************
  92. NAME: CRITSEC::Enter
  93. SYNOPSIS: Enters a critical section
  94. ENTRY: No parameters
  95. EXIT: No return value; critical section is owned by
  96. the calling thread
  97. NOTES: This function is private, and is invoked indirectly
  98. by the friend class TAKE_CRITSEC.
  99. HISTORY:
  100. gregj 11/01/93 Created
  101. ********************************************************************/
  102. void CRITSEC::Enter()
  103. {
  104. #ifdef DEBUG
  105. UIASSERT(_fInitialized != 0);
  106. #endif
  107. ::EnterCriticalSection(&_critsec);
  108. #ifdef DEBUG
  109. _wClaimCount++;
  110. #endif
  111. }
  112. /*******************************************************************
  113. NAME: CRITSEC::Leave
  114. SYNOPSIS: Leaves a critical section
  115. ENTRY: No parameters
  116. EXIT: No return value; critical section is released
  117. NOTES: This function is private, and is invoked indirectly
  118. by the friend class TAKE_CRITSEC.
  119. HISTORY:
  120. gregj 11/01/93 Created
  121. ********************************************************************/
  122. void CRITSEC::Leave()
  123. {
  124. #ifdef DEBUG
  125. UIASSERT(_fInitialized != 0);
  126. UIASSERT(_wClaimCount > 0);
  127. _wClaimCount--;
  128. #endif
  129. ::LeaveCriticalSection(&_critsec);
  130. }
  131. #endif /* DEBUG */
  132. #endif /* 0 */