Skip to content

Commit

Permalink
Port some CoreRT Threading classes to Mono (#47333)
Browse files Browse the repository at this point in the history
  • Loading branch information
CoffeeFlux authored Mar 13, 2021
1 parent 2b55b10 commit 6791d05
Show file tree
Hide file tree
Showing 61 changed files with 970 additions and 10,365 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Runtime.InteropServices;

internal partial class Interop
{
internal partial class Kernel32
{
[DllImport(Libraries.Kernel32)]
[SuppressGCTransition]
internal static extern int GetLastError();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Microsoft.Win32.SafeHandles;
using System;
using System.Runtime.InteropServices;

internal static partial class Interop
{
internal static partial class Kernel32
{
internal const int WAIT_FAILED = unchecked((int)0xFFFFFFFF);

[DllImport(Libraries.Kernel32)]
internal static extern uint WaitForMultipleObjectsEx(uint nCount, IntPtr lpHandles, BOOL bWaitAll, uint dwMilliseconds, BOOL bAlertable);

[DllImport(Libraries.Kernel32)]
internal static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds);

[DllImport(Libraries.Kernel32)]
internal static extern uint SignalObjectAndWait(IntPtr hObjectToSignal, IntPtr hObjectToWaitOn, uint dwMilliseconds, BOOL bAlertable);

[DllImport(Libraries.Kernel32)]
internal static extern void Sleep(uint milliseconds);

internal const uint CREATE_SUSPENDED = 0x00000004;
internal const uint STACK_SIZE_PARAM_IS_A_RESERVATION = 0x00010000;

[DllImport(Libraries.Kernel32)]
internal static extern unsafe SafeWaitHandle CreateThread(
IntPtr lpThreadAttributes,
IntPtr dwStackSize,
delegate* unmanaged<IntPtr, uint> lpStartAddress,
IntPtr lpParameter,
uint dwCreationFlags,
out uint lpThreadId);

[DllImport(Libraries.Kernel32)]
internal static extern uint ResumeThread(SafeWaitHandle hThread);

[DllImport(Libraries.Kernel32)]
internal static extern IntPtr GetCurrentThread();

internal const int DUPLICATE_SAME_ACCESS = 2;

[DllImport(Libraries.Kernel32, SetLastError = true)]
internal static extern bool DuplicateHandle(
IntPtr hSourceProcessHandle,
IntPtr hSourceHandle,
IntPtr hTargetProcessHandle,
out SafeWaitHandle lpTargetHandle,
uint dwDesiredAccess,
bool bInheritHandle,
uint dwOptions);

internal enum ThreadPriority : int
{
Idle = -15,
Lowest = -2,
BelowNormal = -1,
Normal = 0,
AboveNormal = 1,
Highest = 2,
TimeCritical = 15,

ErrorReturn = 0x7FFFFFFF
}

[DllImport(Libraries.Kernel32)]
internal static extern ThreadPriority GetThreadPriority(SafeWaitHandle hThread);

[DllImport(Libraries.Kernel32)]
internal static extern bool SetThreadPriority(SafeWaitHandle hThread, int nPriority);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@
// create unique identities for every test to allow every test to have
// it's own store.
[assembly: CollectionBehavior(CollectionBehavior.CollectionPerAssembly, DisableTestParallelization = true)]
[assembly: ActiveIssue("https://github.com/dotnet/runtime/issues/48720", TestPlatforms.AnyUnix, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)]
[assembly: SkipOnMono("System.IO.IsolatedStorage is not supported on Browser", TestPlatforms.Browser)]
Original file line number Diff line number Diff line change
Expand Up @@ -2998,6 +2998,9 @@
<data name="Overflow_Int64" xml:space="preserve">
<value>Value was either too large or too small for an Int64.</value>
</data>
<data name="Overflow_MutexReacquireCount" xml:space="preserve">
<value>The current thread attempted to reacquire a mutex that has reached its maximum acquire count.</value>
</data>
<data name="Overflow_NegateTwosCompNum" xml:space="preserve">
<value>Negating the minimum value of a twos complement number is invalid.</value>
</data>
Expand Down Expand Up @@ -3577,6 +3580,9 @@
<data name="InvalidOperation_InvalidComUnRegFunctionSig" xml:space="preserve">
<value>COM unregister function must have a System.Type parameter and a void return type.</value>
</data>
<data name="InvalidOperation_InvalidHandle" xml:space="preserve">
<value>The handle is invalid.</value>
</data>
<data name="InvalidOperation_MultipleComRegFunctions" xml:space="preserve">
<value>Type '{0}' has more than one COM registration function.</value>
</data>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1980,4 +1980,24 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\LowLevelLifoSemaphore.Windows.cs" Condition="'$(TargetsWindows)' == 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\RegisteredWaitHandle.Portable.cs" />
</ItemGroup>
<ItemGroup Condition="'$(FeatureCoreCLR)' != 'true' and ('$(TargetsUnix)' == 'true' or '$(TargetsBrowser)' == 'true')">
<Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\SafeHandles\SafeWaitHandle.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\EventWaitHandle.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\Mutex.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\Semaphore.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\WaitHandle.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\WaitSubsystem.HandleManager.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\WaitSubsystem.ThreadWaitInfo.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\WaitSubsystem.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\WaitSubsystem.WaitableObject.Unix.cs" />
</ItemGroup>
<ItemGroup Condition="'$(FeatureCoreCLR)' != 'true' and '$(TargetsWindows)' == 'true'">
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\WaitHandle.Windows.cs" />
<Compile Include="$(CommonPath)\Interop\Windows\Kernel32\Interop.GetLastError.cs">
<Link>Interop\Windows\Kernel32\Interop.GetLastError.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\Windows\Kernel32\Interop.Threading.cs">
<Link>Interop\Windows\Kernel32\Interop.Threading.cs</Link>
</Compile>
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,13 @@ public void DangerousAddRef(ref bool success)
success = true;
}

// Used by internal callers to avoid declaring a bool to pass by ref
internal void DangerousAddRef()
{
bool success = false;
DangerousAddRef(ref success);
}

public void DangerousRelease() => InternalRelease(disposeOrFinalizeOperation: false);

private void InternalRelease(bool disposeOrFinalizeOperation)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace System.Threading
{
public partial class EventWaitHandle
{
private void CreateEventCore(bool initialState, EventResetMode mode, string name, out bool createdNew)
private void CreateEventCore(bool initialState, EventResetMode mode, string? name, out bool createdNew)
{
if (name != null)
throw new PlatformNotSupportedException(SR.PlatformNotSupported_NamedSynchronizationPrimitives);
Expand All @@ -19,7 +19,7 @@ private void CreateEventCore(bool initialState, EventResetMode mode, string name
createdNew = true;
}

private static OpenExistingResult OpenExistingWorker(string name, out EventWaitHandle result)
private static OpenExistingResult OpenExistingWorker(string name, out EventWaitHandle? result)
{
throw new PlatformNotSupportedException(SR.PlatformNotSupported_NamedSynchronizationPrimitives);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,19 @@ private void WaitCore()
Interop.Sys.LowLevelMonitor_Wait(_nativeMonitor);
}

private bool WaitCore(int timeoutMilliseconds)
{
Debug.Assert(timeoutMilliseconds >= -1);

if (timeoutMilliseconds < 0)
{
WaitCore();
return true;
}

return Interop.Sys.LowLevelMonitor_TimedWait(_nativeMonitor, timeoutMilliseconds);
}

private void Signal_ReleaseCore()
{
Interop.Sys.LowLevelMonitor_Signal_Release(_nativeMonitor);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,16 @@ public void Wait()
SetOwnerThreadToCurrent();
}

public bool Wait(int timeoutMilliseconds)
{
Debug.Assert(timeoutMilliseconds >= -1);

ResetOwnerThread();
bool waitResult = WaitCore(timeoutMilliseconds);
SetOwnerThreadToCurrent();
return waitResult;
}

public void Signal_Release()
{
ResetOwnerThread();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ namespace System.Threading
{
public sealed partial class Mutex
{
private void CreateMutexCore(bool initiallyOwned, string name, out bool createdNew)
private void CreateMutexCore(bool initiallyOwned, string? name, out bool createdNew)
{
// See https://github.com/dotnet/runtime/issues/48720
if (name != null)
{
throw new PlatformNotSupportedException(SR.PlatformNotSupported_NamedSynchronizationPrimitives);
Expand All @@ -21,7 +22,7 @@ private void CreateMutexCore(bool initiallyOwned, string name, out bool createdN
createdNew = true;
}

private static OpenExistingResult OpenExistingWorker(string name, out Mutex result)
private static OpenExistingResult OpenExistingWorker(string name, out Mutex? result)
{
throw new PlatformNotSupportedException(SR.PlatformNotSupported_NamedSynchronizationPrimitives);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace System.Threading
{
public sealed partial class Semaphore
{
private void CreateSemaphoreCore(int initialCount, int maximumCount, string name, out bool createdNew)
private void CreateSemaphoreCore(int initialCount, int maximumCount, string? name, out bool createdNew)
{
if (name != null)
{
Expand All @@ -21,7 +21,7 @@ private void CreateSemaphoreCore(int initialCount, int maximumCount, string name
createdNew = true;
}

private static OpenExistingResult OpenExistingWorker(string name, out Semaphore result)
private static OpenExistingResult OpenExistingWorker(string name, out Semaphore? result)
{
throw new PlatformNotSupportedException(SR.PlatformNotSupported_NamedSynchronizationPrimitives);
}
Expand Down
Loading

0 comments on commit 6791d05

Please sign in to comment.