Source code of Windows XP (NT5)
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.

143 lines
2.5 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. exclusive_owner = 0;
  21. hevent = 0;
  22. status = RtlInitializeCriticalSection(&lock);
  23. if (NT_SUCCESS(status))
  24. {
  25. hevent = CreateEvent(0, FALSE, FALSE, 0);
  26. if (0 == hevent)
  27. {
  28. status = OR_NOMEM;
  29. }
  30. }
  31. }
  32. CSharedLock::~CSharedLock()
  33. {
  34. // Cannot be deleted if it failed to initialize
  35. NTSTATUS status = RtlDeleteCriticalSection(&lock);
  36. ASSERT(NT_SUCCESS(status));
  37. if (hevent) CloseHandle(hevent);
  38. }
  39. void
  40. CSharedLock::LockShared()
  41. {
  42. readers++;
  43. if (writers)
  44. {
  45. if ((readers--) == 0)
  46. {
  47. SetEvent(hevent);
  48. }
  49. EnterCriticalSection(&lock);
  50. readers++;
  51. LeaveCriticalSection(&lock);
  52. }
  53. exclusive_owner = 0;
  54. }
  55. void
  56. CSharedLock::UnlockShared(void)
  57. {
  58. ASSERT((LONG)readers > 0);
  59. ASSERT(exclusive_owner == 0);
  60. if ( (readers--) == 0 && writers)
  61. {
  62. SetEvent(hevent);
  63. }
  64. }
  65. void
  66. CSharedLock::LockExclusive(void)
  67. {
  68. EnterCriticalSection(&lock);
  69. writers++;
  70. while(readers)
  71. {
  72. WaitForSingleObject(hevent, INFINITE);
  73. }
  74. ASSERT(writers);
  75. exclusive_owner = GetCurrentThreadId();
  76. }
  77. void
  78. CSharedLock::UnlockExclusive(void)
  79. {
  80. ASSERT(HeldExclusive());
  81. ASSERT(writers);
  82. writers--;
  83. exclusive_owner = 0;
  84. LeaveCriticalSection(&lock);
  85. }
  86. void
  87. CSharedLock::Unlock()
  88. {
  89. // Either the lock is held exclusively by this thread or the thread
  90. // has a shared lock. (or the caller has a bug).
  91. if (HeldExclusive())
  92. {
  93. UnlockExclusive();
  94. }
  95. else
  96. {
  97. UnlockShared();
  98. }
  99. }
  100. void
  101. CSharedLock::ConvertToExclusive(void)
  102. {
  103. ASSERT((LONG)readers > 0);
  104. ASSERT(exclusive_owner == 0);
  105. if ( (readers--) == 0 && writers )
  106. SetEvent(hevent);
  107. EnterCriticalSection(&lock);
  108. writers++;
  109. while(readers)
  110. {
  111. WaitForSingleObject(hevent, INFINITE);
  112. }
  113. ASSERT(writers);
  114. exclusive_owner = GetCurrentThreadId();
  115. }