1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | |
5 | |
6 | /* ---------------------------------------------------------------------------- |
7 | |
8 | ---------------------------------------------------------------------------- */ |
9 | #ifndef __UTSEM_H__ |
10 | #define __UTSEM_H__ |
11 | |
12 | |
13 | // ------------------------------------------------------------- |
14 | // INCLUDES |
15 | // ------------------------------------------------------------- |
16 | #include "utilcode.h" |
17 | |
18 | /* ---------------------------------------------------------------------------- |
19 | @class UTSemReadWrite |
20 | |
21 | An instance of class UTSemReadWrite provides multi-read XOR single-write |
22 | (a.k.a. shared vs. exclusive) lock capabilities, with protection against |
23 | writer starvation. |
24 | |
25 | A thread MUST NOT call any of the Lock methods if it already holds a Lock. |
26 | (Doing so may result in a deadlock.) |
27 | |
28 | |
29 | ---------------------------------------------------------------------------- */ |
30 | class UTSemReadWrite |
31 | { |
32 | public: |
33 | UTSemReadWrite(); // Constructor |
34 | ~UTSemReadWrite(); // Destructor |
35 | |
36 | HRESULT Init(); |
37 | |
38 | HRESULT LockRead(); // Lock the object for reading |
39 | HRESULT LockWrite(); // Lock the object for writing |
40 | void UnlockRead(); // Unlock the object for reading |
41 | void UnlockWrite(); // Unlock the object for writing |
42 | |
43 | #ifdef _DEBUG |
44 | BOOL Debug_IsLockedForRead(); |
45 | BOOL Debug_IsLockedForWrite(); |
46 | #endif //_DEBUG |
47 | |
48 | private: |
49 | Semaphore * GetReadWaiterSemaphore() |
50 | { |
51 | return m_pReadWaiterSemaphore; |
52 | } |
53 | Event * GetWriteWaiterEvent() |
54 | { |
55 | return m_pWriteWaiterEvent; |
56 | } |
57 | |
58 | Volatile<ULONG> m_dwFlag; // internal state, see implementation |
59 | Semaphore * m_pReadWaiterSemaphore; // semaphore for awakening read waiters |
60 | Event * m_pWriteWaiterEvent; // event for awakening write waiters |
61 | }; // class UTSemReadWrite |
62 | |
63 | #endif // __UTSEM_H__ |
64 | |