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.

156 lines
2.8 KiB

  1. /*++
  2. Copyright (c) 1995-1996 Microsoft Corporation
  3. Module Name:
  4. Locks.cxx
  5. Abstract:
  6. Out of line methods for some of the syncronization classes
  7. defined in locks.hxx.
  8. Author:
  9. Mario Goertzel [MarioGo]
  10. Revision History:
  11. MarioGo 03-14-95 Moved from misc.cxx.
  12. MarioGo 01-27-96 Changed from busy (Sleep(0)) wait to event
  13. --*/
  14. #include <or.hxx>
  15. //
  16. // CShareLock methods
  17. //
  18. CSharedLock::CSharedLock(ORSTATUS &status)
  19. {
  20. csinitokay = FALSE;
  21. exclusive_owner = 0;
  22. hevent = 0;
  23. status = OR_NOMEM;
  24. if (NT_SUCCESS(RtlInitializeCriticalSection(&lock)))
  25. {
  26. csinitokay = TRUE;
  27. hevent = CreateEvent(0, FALSE, FALSE, 0);
  28. if (hevent)
  29. {
  30. status = OR_OK;
  31. }
  32. }
  33. }
  34. CSharedLock::~CSharedLock()
  35. {
  36. if (csinitokay)
  37. {
  38. NTSTATUS status = RtlDeleteCriticalSection(&lock);
  39. ASSERT(NT_SUCCESS(status));
  40. }
  41. if (hevent) CloseHandle(hevent);
  42. }
  43. void
  44. CSharedLock::LockShared()
  45. {
  46. AssertValid();
  47. readers++;
  48. if (writers)
  49. {
  50. if ((readers--) == 0)
  51. {
  52. SetEvent(hevent);
  53. }
  54. EnterCriticalSection(&lock);
  55. readers++;
  56. LeaveCriticalSection(&lock);
  57. }
  58. exclusive_owner = 0;
  59. }
  60. void
  61. CSharedLock::UnlockShared(void)
  62. {
  63. AssertValid();
  64. ASSERT((LONG)readers > 0);
  65. ASSERT(exclusive_owner == 0);
  66. if ( (readers--) == 0 && writers)
  67. {
  68. SetEvent(hevent);
  69. }
  70. }
  71. void
  72. CSharedLock::LockExclusive(void)
  73. {
  74. AssertValid();
  75. EnterCriticalSection(&lock);
  76. writers++;
  77. while(readers)
  78. {
  79. WaitForSingleObject(hevent, INFINITE);
  80. }
  81. ASSERT(writers);
  82. exclusive_owner = GetCurrentThreadId();
  83. }
  84. void
  85. CSharedLock::UnlockExclusive(void)
  86. {
  87. AssertValid();
  88. ASSERT(HeldExclusive());
  89. ASSERT(writers);
  90. writers--;
  91. exclusive_owner = 0;
  92. LeaveCriticalSection(&lock);
  93. }
  94. void
  95. CSharedLock::Unlock()
  96. {
  97. AssertValid();
  98. // Either the lock is held exclusively by this thread or the thread
  99. // has a shared lock. (or the caller has a bug).
  100. if (HeldExclusive())
  101. {
  102. UnlockExclusive();
  103. }
  104. else
  105. {
  106. UnlockShared();
  107. }
  108. }
  109. void
  110. CSharedLock::ConvertToExclusive(void)
  111. {
  112. AssertValid();
  113. ASSERT((LONG)readers > 0);
  114. ASSERT(exclusive_owner == 0);
  115. if ( (readers--) == 0 && writers )
  116. SetEvent(hevent);
  117. EnterCriticalSection(&lock);
  118. writers++;
  119. while(readers)
  120. {
  121. WaitForSingleObject(hevent, INFINITE);
  122. }
  123. ASSERT(writers);
  124. exclusive_owner = GetCurrentThreadId();
  125. }