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.Collections.Generic;
6 using System.Diagnostics;
7 using System.Runtime;
8 using System.Runtime.InteropServices;
9 
10 namespace System.Threading
11 {
12     internal static partial class WaitSubsystem
13     {
14         private static class HandleManager
15         {
NewHandle(WaitableObject waitableObject)16             public static IntPtr NewHandle(WaitableObject waitableObject)
17             {
18                 Debug.Assert(waitableObject != null);
19 
20                 IntPtr handle = RuntimeImports.RhHandleAlloc(waitableObject, GCHandleType.Normal);
21 
22                 // SafeWaitHandle treats -1 and 0 as invalid, and the handle should not be these values anyway
23                 Debug.Assert(handle != IntPtr.Zero);
24                 Debug.Assert(handle != new IntPtr(-1));
25                 return handle;
26             }
27 
FromHandle(IntPtr handle)28             public static WaitableObject FromHandle(IntPtr handle)
29             {
30                 if (handle == IntPtr.Zero || handle == new IntPtr(-1))
31                 {
32                     WaitHandle.ThrowInvalidHandleException();
33                 }
34 
35                 // We don't know if any other handles are invalid, and this may crash or otherwise do bad things, that is by
36                 // design, IntPtr is unsafe by nature.
37                 return (WaitableObject)RuntimeImports.RhHandleGet(handle);
38             }
39 
40             /// <summary>
41             /// Unlike on Windows, a handle may not be deleted more than once with this implementation
42             /// </summary>
DeleteHandle(IntPtr handle)43             public static void DeleteHandle(IntPtr handle)
44             {
45                 if (handle == IntPtr.Zero || handle == new IntPtr(-1))
46                 {
47                     return;
48                 }
49 
50                 // We don't know if any other handles are invalid, and this may crash or otherwise do bad things, that is by
51                 // design, IntPtr is unsafe by nature.
52                 ((WaitableObject)RuntimeImports.RhHandleGet(handle)).OnDeleteHandle();
53                 RuntimeImports.RhHandleFree(handle);
54             }
55         }
56     }
57 }
58