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.

146 lines
3.9 KiB

  1. //============================================================================
  2. // Copyright (c) 1996, Microsoft Corporation
  3. //
  4. // File: sync.c
  5. //
  6. // History:
  7. // Abolade Gbadegesin Jan-12-1996 Created.
  8. //
  9. // Implementation of synchronization routines.
  10. //============================================================================
  11. #include "pchqosm.h"
  12. #pragma hdrstop
  13. #ifdef USE_RWL
  14. //----------------------------------------------------------------------------
  15. // Function: CreateReadWriteLock
  16. //
  17. // Initializes a multiple-reader/single-writer lock object
  18. //----------------------------------------------------------------------------
  19. DWORD
  20. CreateReadWriteLock(
  21. PREAD_WRITE_LOCK pRWL
  22. )
  23. {
  24. pRWL->RWL_ReaderCount = 0;
  25. try {
  26. InitializeCriticalSection(&(pRWL)->RWL_ReadWriteBlock);
  27. }
  28. except (EXCEPTION_EXECUTE_HANDLER) {
  29. return GetLastError();
  30. }
  31. pRWL->RWL_ReaderDoneEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
  32. if (pRWL->RWL_ReaderDoneEvent != NULL) {
  33. return GetLastError();
  34. }
  35. return NO_ERROR;
  36. }
  37. //----------------------------------------------------------------------------
  38. // Function: DeleteReadWriteLock
  39. //
  40. // Frees resources used by a multiple-reader/single-writer lock object
  41. //----------------------------------------------------------------------------
  42. VOID
  43. DeleteReadWriteLock(
  44. PREAD_WRITE_LOCK pRWL
  45. )
  46. {
  47. CloseHandle(pRWL->RWL_ReaderDoneEvent);
  48. pRWL->RWL_ReaderDoneEvent = NULL;
  49. DeleteCriticalSection(&pRWL->RWL_ReadWriteBlock);
  50. pRWL->RWL_ReaderCount = 0;
  51. }
  52. //----------------------------------------------------------------------------
  53. // Function: AcquireReadLock
  54. //
  55. // Secures shared ownership of the lock object for the caller.
  56. //
  57. // readers enter the read-write critical section, increment the count,
  58. // and leave the critical section
  59. //----------------------------------------------------------------------------
  60. VOID
  61. AcquireReadLock(
  62. PREAD_WRITE_LOCK pRWL
  63. )
  64. {
  65. EnterCriticalSection(&pRWL->RWL_ReadWriteBlock);
  66. InterlockedIncrement(&pRWL->RWL_ReaderCount);
  67. LeaveCriticalSection(&pRWL->RWL_ReadWriteBlock);
  68. }
  69. //----------------------------------------------------------------------------
  70. // Function: ReleaseReadLock
  71. //
  72. // Relinquishes shared ownership of the lock object.
  73. //
  74. // the last reader sets the event to wake any waiting writers
  75. //----------------------------------------------------------------------------
  76. VOID
  77. ReleaseReadLock(
  78. PREAD_WRITE_LOCK pRWL
  79. )
  80. {
  81. if (InterlockedDecrement(&pRWL->RWL_ReaderCount) < 0)
  82. SetEvent(pRWL->RWL_ReaderDoneEvent);
  83. }
  84. //----------------------------------------------------------------------------
  85. // Function: AcquireWriteLock
  86. //
  87. // Secures exclusive ownership of the lock object.
  88. //
  89. // the writer blocks other threads by entering the ReadWriteBlock section,
  90. // and then waits for any thread(s) owning the lock to finish
  91. //----------------------------------------------------------------------------
  92. VOID
  93. AcquireWriteLock(
  94. PREAD_WRITE_LOCK pRWL
  95. )
  96. {
  97. EnterCriticalSection(&pRWL->RWL_ReadWriteBlock);
  98. if (InterlockedDecrement(&pRWL->RWL_ReaderCount) >= 0)
  99. WaitForSingleObject(pRWL->RWL_ReaderDoneEvent, INFINITE);
  100. }
  101. //----------------------------------------------------------------------------
  102. // Function: ReleaseWriteLock
  103. //
  104. // Relinquishes exclusive ownership of the lock object.
  105. //
  106. // the writer releases the lock by setting the count to zero
  107. // and then leaving the ReadWriteBlock critical section
  108. //----------------------------------------------------------------------------
  109. VOID
  110. ReleaseWriteLock(
  111. PREAD_WRITE_LOCK pRWL
  112. )
  113. {
  114. pRWL->RWL_ReaderCount = 0;
  115. LeaveCriticalSection(&(pRWL)->RWL_ReadWriteBlock);
  116. }
  117. #endif // USE_RWL