Skip to content

Commit 4714795

Browse files
author
Koundinya Veluri
committed
Simplify mutex/semaphore/event creation paths for APIs without a name argument
1 parent f53d700 commit 4714795

File tree

10 files changed

+117
-27
lines changed

10 files changed

+117
-27
lines changed

src/coreclr/System.Private.CoreLib/src/System/Threading/Mutex.CoreCLR.Unix.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,25 @@ namespace System.Threading
1414
/// </summary>
1515
public sealed partial class Mutex : WaitHandle
1616
{
17+
private unsafe void CreateMutexCore(bool initiallyOwned)
18+
{
19+
SafeWaitHandle handle =
20+
CreateMutex(
21+
initiallyOwned,
22+
name: null,
23+
currentUserOnly: false,
24+
systemCallErrors: null,
25+
systemCallErrorsBufferSize: 0);
26+
if (handle.IsInvalid)
27+
{
28+
int errorCode = Marshal.GetLastPInvokeError();
29+
handle.SetHandleAsInvalid();
30+
throw Win32Marshal.GetExceptionForWin32Error(errorCode);
31+
}
32+
33+
SafeWaitHandle = handle;
34+
}
35+
1736
private void CreateMutexCore(
1837
bool initiallyOwned,
1938
string? name,

src/libraries/System.Private.CoreLib/src/System/Threading/EventWaitHandle.Unix.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ namespace System.Threading
1010
{
1111
public partial class EventWaitHandle
1212
{
13+
private void CreateEventCore(bool initialState, EventResetMode mode)
14+
{
15+
ValidateMode(mode);
16+
SafeWaitHandle = WaitSubsystem.NewEvent(initialState, mode);
17+
}
18+
1319
#pragma warning disable IDE0060 // Unused parameter
1420
private void CreateEventCore(
1521
bool initialState,
@@ -18,10 +24,7 @@ private void CreateEventCore(
1824
NamedWaitHandleOptionsInternal options,
1925
out bool createdNew)
2026
{
21-
if (mode != EventResetMode.AutoReset && mode != EventResetMode.ManualReset)
22-
{
23-
throw new ArgumentException(SR.Argument_InvalidFlag, nameof(mode));
24-
}
27+
ValidateMode(mode);
2528

2629
if (name != null)
2730
{

src/libraries/System.Private.CoreLib/src/System/Threading/EventWaitHandle.Windows.cs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,32 @@ private EventWaitHandle(SafeWaitHandle handle)
2222
SafeWaitHandle = handle;
2323
}
2424

25+
private unsafe void CreateEventCore(bool initialState, EventResetMode mode)
26+
{
27+
ValidateMode(mode);
28+
29+
uint flags = initialState ? Interop.Kernel32.CREATE_EVENT_INITIAL_SET : 0;
30+
if (mode == EventResetMode.ManualReset)
31+
flags |= Interop.Kernel32.CREATE_EVENT_MANUAL_RESET;
32+
SafeWaitHandle handle = Interop.Kernel32.CreateEventEx(lpSecurityAttributes: 0, name: null, flags, AccessRights);
33+
if (handle.IsInvalid)
34+
{
35+
int errorCode = Marshal.GetLastPInvokeError();
36+
handle.SetHandleAsInvalid();
37+
throw Win32Marshal.GetExceptionForWin32Error(errorCode);
38+
}
39+
40+
SafeWaitHandle = handle;
41+
}
42+
2543
private unsafe void CreateEventCore(
2644
bool initialState,
2745
EventResetMode mode,
2846
string? name,
2947
NamedWaitHandleOptionsInternal options,
3048
out bool createdNew)
3149
{
32-
if (mode != EventResetMode.AutoReset && mode != EventResetMode.ManualReset)
33-
{
34-
throw new ArgumentException(SR.Argument_InvalidFlag, nameof(mode));
35-
}
50+
ValidateMode(mode);
3651

3752
#if !TARGET_WINDOWS
3853
if (name != null)

src/libraries/System.Private.CoreLib/src/System/Threading/EventWaitHandle.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public partial class EventWaitHandle : WaitHandle
1212
{
1313
public EventWaitHandle(bool initialState, EventResetMode mode)
1414
{
15-
CreateEventCore(initialState, mode, name: null, options: default, out _);
15+
CreateEventCore(initialState, mode);
1616
}
1717

1818
/// <summary>
@@ -64,6 +64,14 @@ public EventWaitHandle(bool initialState, EventResetMode mode, string? name, out
6464
CreateEventCore(initialState, mode, name, options: default, out createdNew);
6565
}
6666

67+
private static void ValidateMode(EventResetMode mode)
68+
{
69+
if (mode != EventResetMode.AutoReset && mode != EventResetMode.ManualReset)
70+
{
71+
throw new ArgumentException(SR.Argument_InvalidFlag, nameof(mode));
72+
}
73+
}
74+
6775
/// <summary>
6876
/// Opens an existing named event.
6977
/// </summary>

src/libraries/System.Private.CoreLib/src/System/Threading/Mutex.Unix.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ namespace System.Threading
1010
{
1111
public sealed partial class Mutex
1212
{
13+
private void CreateMutexCore(bool initiallyOwned) => SafeWaitHandle = WaitSubsystem.NewMutex(initiallyOwned);
14+
1315
private void CreateMutexCore(
1416
bool initiallyOwned,
1517
string? name,

src/libraries/System.Private.CoreLib/src/System/Threading/Mutex.Windows.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,20 @@ public sealed partial class Mutex : WaitHandle
1919
private const int CurrentUserOnlyAceRights =
2020
Interop.Kernel32.STANDARD_RIGHTS_REQUIRED | Interop.Kernel32.SYNCHRONIZE | Interop.Kernel32.MUTEX_MODIFY_STATE;
2121

22+
private void CreateMutexCore(bool initiallyOwned)
23+
{
24+
uint flags = initiallyOwned ? Interop.Kernel32.CREATE_MUTEX_INITIAL_OWNER : 0;
25+
SafeWaitHandle handle = Interop.Kernel32.CreateMutexEx(lpMutexAttributes: 0, name: null, flags, AccessRights);
26+
if (handle.IsInvalid)
27+
{
28+
int errorCode = Marshal.GetLastPInvokeError();
29+
handle.SetHandleAsInvalid();
30+
throw Win32Marshal.GetExceptionForWin32Error(errorCode);
31+
}
32+
33+
SafeWaitHandle = handle;
34+
}
35+
2236
private unsafe void CreateMutexCore(
2337
bool initiallyOwned,
2438
string? name,

src/libraries/System.Private.CoreLib/src/System/Threading/Mutex.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,12 @@ public Mutex(string? name, NamedWaitHandleOptions options)
8282

8383
public Mutex(bool initiallyOwned)
8484
{
85-
CreateMutexCore(initiallyOwned, name: null, options: default, createdNew: out _);
85+
CreateMutexCore(initiallyOwned);
8686
}
8787

8888
public Mutex()
8989
{
90-
CreateMutexCore(initiallyOwned: false, name: null, options: default, createdNew: out _);
90+
CreateMutexCore(initiallyOwned: false);
9191
}
9292

9393
private Mutex(SafeWaitHandle handle)

src/libraries/System.Private.CoreLib/src/System/Threading/Semaphore.Unix.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ namespace System.Threading
1010
{
1111
public sealed partial class Semaphore
1212
{
13+
private void CreateSemaphoreCore(int initialCount, int maximumCount)
14+
{
15+
ValidateArguments(initialCount, maximumCount);
16+
SafeWaitHandle = WaitSubsystem.NewSemaphore(initialCount, maximumCount);
17+
}
18+
1319
#pragma warning disable IDE0060 // Unused parameter
1420
private void CreateSemaphoreCore(
1521
int initialCount,
@@ -18,13 +24,7 @@ private void CreateSemaphoreCore(
1824
NamedWaitHandleOptionsInternal options,
1925
out bool createdNew)
2026
{
21-
ArgumentOutOfRangeException.ThrowIfNegative(initialCount);
22-
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(maximumCount);
23-
24-
if (initialCount > maximumCount)
25-
{
26-
throw new ArgumentException(SR.Argument_SemaphoreInitialMaximum);
27-
}
27+
ValidateArguments(initialCount, maximumCount);
2828

2929
if (name != null)
3030
{

src/libraries/System.Private.CoreLib/src/System/Threading/Semaphore.Windows.cs

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,36 @@ private Semaphore(SafeWaitHandle handle)
2222
SafeWaitHandle = handle;
2323
}
2424

25+
private void CreateSemaphoreCore(int initialCount, int maximumCount)
26+
{
27+
ValidateArguments(initialCount, maximumCount);
28+
29+
SafeWaitHandle handle =
30+
Interop.Kernel32.CreateSemaphoreEx(
31+
lpSecurityAttributes: 0,
32+
initialCount,
33+
maximumCount,
34+
name: null,
35+
flags: 0,
36+
AccessRights);
37+
if (handle.IsInvalid)
38+
{
39+
int errorCode = Marshal.GetLastPInvokeError();
40+
handle.SetHandleAsInvalid();
41+
throw Win32Marshal.GetExceptionForWin32Error(errorCode);
42+
}
43+
44+
SafeWaitHandle = handle;
45+
}
46+
2547
private unsafe void CreateSemaphoreCore(
2648
int initialCount,
2749
int maximumCount,
2850
string? name,
2951
NamedWaitHandleOptionsInternal options,
3052
out bool createdNew)
3153
{
32-
ArgumentOutOfRangeException.ThrowIfNegative(initialCount);
33-
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(maximumCount);
34-
35-
if (initialCount > maximumCount)
36-
{
37-
throw new ArgumentException(SR.Argument_SemaphoreInitialMaximum);
38-
}
54+
ValidateArguments(initialCount, maximumCount);
3955

4056
#if !TARGET_WINDOWS
4157
if (name != null)
@@ -77,11 +93,13 @@ private unsafe void CreateSemaphoreCore(
7793

7894
if (myHandle.IsInvalid)
7995
{
80-
myHandle.Dispose();
96+
myHandle.SetHandleAsInvalid();
8197

8298
if (!string.IsNullOrEmpty(name) && errorCode == Interop.Errors.ERROR_INVALID_HANDLE)
99+
{
83100
throw new WaitHandleCannotBeOpenedException(
84101
SR.Format(SR.Threading_WaitHandleCannotBeOpenedException_InvalidHandle, name));
102+
}
85103

86104
throw Win32Marshal.GetExceptionForWin32Error(errorCode, name);
87105
}

src/libraries/System.Private.CoreLib/src/System/Threading/Semaphore.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public sealed partial class Semaphore : WaitHandle
1414
// Win32 only takes maximum count of int.MaxValue
1515
public Semaphore(int initialCount, int maximumCount)
1616
{
17-
CreateSemaphoreCore(initialCount, maximumCount, name: null, options: default, out _);
17+
CreateSemaphoreCore(initialCount, maximumCount);
1818
}
1919

2020
/// <summary>
@@ -74,6 +74,17 @@ public Semaphore(int initialCount, int maximumCount, string? name, out bool crea
7474
CreateSemaphoreCore(initialCount, maximumCount, name, options: default, out createdNew);
7575
}
7676

77+
private static void ValidateArguments(int initialCount, int maximumCount)
78+
{
79+
ArgumentOutOfRangeException.ThrowIfNegative(initialCount);
80+
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(maximumCount);
81+
82+
if (initialCount > maximumCount)
83+
{
84+
throw new ArgumentException(SR.Argument_SemaphoreInitialMaximum);
85+
}
86+
}
87+
7788
/// <summary>
7889
/// Opens an existing named semaphore.
7990
/// </summary>

0 commit comments

Comments
 (0)