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 using System.Diagnostics;
6 using Internal.Runtime.Augments;
7 
8 namespace System.Threading
9 {
10     /// <summary>
11     /// Wraps a non-recursive mutex and condition.
12     ///
13     /// Used by the wait subsystem on Unix, so this class cannot have any dependencies on the wait subsystem.
14     /// </summary>
15     internal sealed partial class LowLevelMonitor : IDisposable
16     {
17         private IntPtr _nativeMonitor;
18 
LowLevelMonitor()19         public LowLevelMonitor()
20         {
21             _nativeMonitor = Interop.Sys.LowLevelMonitor_New();
22             if (_nativeMonitor == IntPtr.Zero)
23             {
24                 throw new OutOfMemoryException();
25             }
26         }
27 
DisposeCore()28         private void DisposeCore()
29         {
30             if (_nativeMonitor == IntPtr.Zero)
31             {
32                 return;
33             }
34 
35             Interop.Sys.LowLevelMonitor_Delete(_nativeMonitor);
36             _nativeMonitor = IntPtr.Zero;
37         }
38 
AcquireCore()39         private void AcquireCore()
40         {
41             Interop.Sys.LowLevelMutex_Acquire(_nativeMonitor);
42         }
43 
ReleaseCore()44         private void ReleaseCore()
45         {
46             Interop.Sys.LowLevelMutex_Release(_nativeMonitor);
47         }
48 
WaitCore()49         private void WaitCore()
50         {
51             Interop.Sys.LowLevelMonitor_Wait(_nativeMonitor);
52         }
53 
WaitCore(int timeoutMilliseconds)54         private bool WaitCore(int timeoutMilliseconds)
55         {
56             Debug.Assert(timeoutMilliseconds >= -1);
57 
58             if (timeoutMilliseconds < 0)
59             {
60                 WaitCore();
61                 return true;
62             }
63 
64             return Interop.Sys.LowLevelMonitor_TimedWait(_nativeMonitor, timeoutMilliseconds);
65         }
66 
Signal_ReleaseCore()67         private void Signal_ReleaseCore()
68         {
69             Interop.Sys.LowLevelMonitor_Signal_Release(_nativeMonitor);
70         }
71     }
72 }
73