You've already forked linux-packaging-mono
Imported Upstream version 5.0.0.42
Former-commit-id: fd56571888259555122d8a0f58c68838229cea2b
This commit is contained in:
parent
1190d13a04
commit
6bdd276d05
80
external/corefx/src/System.Threading.Overlapped/System.Threading.Overlapped.sln
vendored
Normal file
80
external/corefx/src/System.Threading.Overlapped/System.Threading.Overlapped.sln
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.23107.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Threading.Overlapped.Tests", "tests\System.Threading.Overlapped.Tests.csproj", "{861A3318-35AD-46AC-8257-8D5D2479BAD9}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{6A07CCB8-3E59-47E7-B3DD-DB1F6FC501D5} = {6A07CCB8-3E59-47E7-B3DD-DB1F6FC501D5}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Threading.Overlapped", "src\System.Threading.Overlapped.csproj", "{6A07CCB8-3E59-47E7-B3DD-DB1F6FC501D5}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
DebugNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU = DebugNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU
|
||||
ReleaseNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU = ReleaseNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU
|
||||
DebugNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU = DebugNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU
|
||||
ReleaseNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU = ReleaseNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU
|
||||
DebugNETCoreAppnetcoreapp-Windows_NTnetcoreapp-Windows_NT|AnyCPU = DebugNETCoreAppnetcoreapp-Windows_NTnetcoreapp-Windows_NT|AnyCPU
|
||||
ReleaseNETCoreAppnetcoreapp-Windows_NTnetcoreapp-Windows_NT|AnyCPU = ReleaseNETCoreAppnetcoreapp-Windows_NTnetcoreapp-Windows_NT|AnyCPU
|
||||
DebugNETCoreAppnetcoreapp-Windows_NTnetcoreapp-Windows_NT|AnyCPU = DebugNETCoreAppnetcoreapp-Windows_NTnetcoreapp-Windows_NT|AnyCPU
|
||||
ReleaseNETCoreAppnetcoreapp-Windows_NTnetcoreapp-Windows_NT|AnyCPU = ReleaseNETCoreAppnetcoreapp-Windows_NTnetcoreapp-Windows_NT|AnyCPU
|
||||
DebugNETCoreAppnetcoreapp-Unixnetcoreapp-Windows_NT|AnyCPU = DebugNETCoreAppnetcoreapp-Unixnetcoreapp-Windows_NT|AnyCPU
|
||||
ReleaseNETCoreAppnetcoreapp-Unixnetcoreapp-Windows_NT|AnyCPU = ReleaseNETCoreAppnetcoreapp-Unixnetcoreapp-Windows_NT|AnyCPU
|
||||
DebugNETCoreAppnetcoreapp-Unixnetcoreapp-Windows_NT|AnyCPU = DebugNETCoreAppnetcoreapp-Unixnetcoreapp-Windows_NT|AnyCPU
|
||||
ReleaseNETCoreAppnetcoreapp-Unixnetcoreapp-Windows_NT|AnyCPU = ReleaseNETCoreAppnetcoreapp-Unixnetcoreapp-Windows_NT|AnyCPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{861A3318-35AD-46AC-8257-8D5D2479BAD9}.DebugNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU.ActiveCfg = netcoreapp-Windows_NT-Debug|Any CPU
|
||||
{861A3318-35AD-46AC-8257-8D5D2479BAD9}.DebugNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU.Build.0 = netcoreapp-Windows_NT-Debug|Any CPU
|
||||
{861A3318-35AD-46AC-8257-8D5D2479BAD9}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU.ActiveCfg = netcoreapp-Windows_NT-Release|Any CPU
|
||||
{861A3318-35AD-46AC-8257-8D5D2479BAD9}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU.Build.0 = netcoreapp-Windows_NT-Release|Any CPU
|
||||
{861A3318-35AD-46AC-8257-8D5D2479BAD9}.DebugNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU.ActiveCfg = netcoreapp-Windows_NT-Debug|Any CPU
|
||||
{861A3318-35AD-46AC-8257-8D5D2479BAD9}.DebugNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU.Build.0 = netcoreapp-Windows_NT-Debug|Any CPU
|
||||
{861A3318-35AD-46AC-8257-8D5D2479BAD9}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU.ActiveCfg = netcoreapp-Windows_NT-Release|Any CPU
|
||||
{861A3318-35AD-46AC-8257-8D5D2479BAD9}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU.Build.0 = netcoreapp-Windows_NT-Release|Any CPU
|
||||
{861A3318-35AD-46AC-8257-8D5D2479BAD9}.DebugNETCoreAppnetcoreapp-Windows_NTnetcoreapp-Windows_NT|AnyCPU.ActiveCfg = netcoreapp-Windows_NT-Debug|Any CPU
|
||||
{861A3318-35AD-46AC-8257-8D5D2479BAD9}.DebugNETCoreAppnetcoreapp-Windows_NTnetcoreapp-Windows_NT|AnyCPU.Build.0 = netcoreapp-Windows_NT-Debug|Any CPU
|
||||
{861A3318-35AD-46AC-8257-8D5D2479BAD9}.ReleaseNETCoreAppnetcoreapp-Windows_NTnetcoreapp-Windows_NT|AnyCPU.ActiveCfg = netcoreapp-Windows_NT-Release|Any CPU
|
||||
{861A3318-35AD-46AC-8257-8D5D2479BAD9}.ReleaseNETCoreAppnetcoreapp-Windows_NTnetcoreapp-Windows_NT|AnyCPU.Build.0 = netcoreapp-Windows_NT-Release|Any CPU
|
||||
{861A3318-35AD-46AC-8257-8D5D2479BAD9}.DebugNETCoreAppnetcoreapp-Windows_NTnetcoreapp-Windows_NT|AnyCPU.ActiveCfg = netcoreapp-Windows_NT-Debug|Any CPU
|
||||
{861A3318-35AD-46AC-8257-8D5D2479BAD9}.DebugNETCoreAppnetcoreapp-Windows_NTnetcoreapp-Windows_NT|AnyCPU.Build.0 = netcoreapp-Windows_NT-Debug|Any CPU
|
||||
{861A3318-35AD-46AC-8257-8D5D2479BAD9}.ReleaseNETCoreAppnetcoreapp-Windows_NTnetcoreapp-Windows_NT|AnyCPU.ActiveCfg = netcoreapp-Windows_NT-Release|Any CPU
|
||||
{861A3318-35AD-46AC-8257-8D5D2479BAD9}.ReleaseNETCoreAppnetcoreapp-Windows_NTnetcoreapp-Windows_NT|AnyCPU.Build.0 = netcoreapp-Windows_NT-Release|Any CPU
|
||||
{861A3318-35AD-46AC-8257-8D5D2479BAD9}.DebugNETCoreAppnetcoreapp-Unixnetcoreapp-Windows_NT|AnyCPU.ActiveCfg = netcoreapp-Windows_NT-Debug|Any CPU
|
||||
{861A3318-35AD-46AC-8257-8D5D2479BAD9}.DebugNETCoreAppnetcoreapp-Unixnetcoreapp-Windows_NT|AnyCPU.Build.0 = netcoreapp-Windows_NT-Debug|Any CPU
|
||||
{861A3318-35AD-46AC-8257-8D5D2479BAD9}.ReleaseNETCoreAppnetcoreapp-Unixnetcoreapp-Windows_NT|AnyCPU.ActiveCfg = netcoreapp-Windows_NT-Release|Any CPU
|
||||
{861A3318-35AD-46AC-8257-8D5D2479BAD9}.ReleaseNETCoreAppnetcoreapp-Unixnetcoreapp-Windows_NT|AnyCPU.Build.0 = netcoreapp-Windows_NT-Release|Any CPU
|
||||
{861A3318-35AD-46AC-8257-8D5D2479BAD9}.DebugNETCoreAppnetcoreapp-Unixnetcoreapp-Windows_NT|AnyCPU.ActiveCfg = netcoreapp-Windows_NT-Debug|Any CPU
|
||||
{861A3318-35AD-46AC-8257-8D5D2479BAD9}.DebugNETCoreAppnetcoreapp-Unixnetcoreapp-Windows_NT|AnyCPU.Build.0 = netcoreapp-Windows_NT-Debug|Any CPU
|
||||
{861A3318-35AD-46AC-8257-8D5D2479BAD9}.ReleaseNETCoreAppnetcoreapp-Unixnetcoreapp-Windows_NT|AnyCPU.ActiveCfg = netcoreapp-Windows_NT-Release|Any CPU
|
||||
{861A3318-35AD-46AC-8257-8D5D2479BAD9}.ReleaseNETCoreAppnetcoreapp-Unixnetcoreapp-Windows_NT|AnyCPU.Build.0 = netcoreapp-Windows_NT-Release|Any CPU
|
||||
{6A07CCB8-3E59-47E7-B3DD-DB1F6FC501D5}.DebugNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU.ActiveCfg = net463-Windows_NT-Debug|Any CPU
|
||||
{6A07CCB8-3E59-47E7-B3DD-DB1F6FC501D5}.DebugNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU.Build.0 = net463-Windows_NT-Debug|Any CPU
|
||||
{6A07CCB8-3E59-47E7-B3DD-DB1F6FC501D5}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU.ActiveCfg = net463-Windows_NT-Release|Any CPU
|
||||
{6A07CCB8-3E59-47E7-B3DD-DB1F6FC501D5}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU.Build.0 = net463-Windows_NT-Release|Any CPU
|
||||
{6A07CCB8-3E59-47E7-B3DD-DB1F6FC501D5}.DebugNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU.ActiveCfg = net463-Windows_NT-Debug|Any CPU
|
||||
{6A07CCB8-3E59-47E7-B3DD-DB1F6FC501D5}.DebugNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU.Build.0 = net463-Windows_NT-Debug|Any CPU
|
||||
{6A07CCB8-3E59-47E7-B3DD-DB1F6FC501D5}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU.ActiveCfg = net463-Windows_NT-Release|Any CPU
|
||||
{6A07CCB8-3E59-47E7-B3DD-DB1F6FC501D5}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp-Windows_NT|AnyCPU.Build.0 = net463-Windows_NT-Release|Any CPU
|
||||
{6A07CCB8-3E59-47E7-B3DD-DB1F6FC501D5}.DebugNETCoreAppnetcoreapp-Windows_NTnetcoreapp-Windows_NT|AnyCPU.ActiveCfg = netcoreapp-Windows_NT-Debug|Any CPU
|
||||
{6A07CCB8-3E59-47E7-B3DD-DB1F6FC501D5}.DebugNETCoreAppnetcoreapp-Windows_NTnetcoreapp-Windows_NT|AnyCPU.Build.0 = netcoreapp-Windows_NT-Debug|Any CPU
|
||||
{6A07CCB8-3E59-47E7-B3DD-DB1F6FC501D5}.ReleaseNETCoreAppnetcoreapp-Windows_NTnetcoreapp-Windows_NT|AnyCPU.ActiveCfg = netcoreapp-Windows_NT-Release|Any CPU
|
||||
{6A07CCB8-3E59-47E7-B3DD-DB1F6FC501D5}.ReleaseNETCoreAppnetcoreapp-Windows_NTnetcoreapp-Windows_NT|AnyCPU.Build.0 = netcoreapp-Windows_NT-Release|Any CPU
|
||||
{6A07CCB8-3E59-47E7-B3DD-DB1F6FC501D5}.DebugNETCoreAppnetcoreapp-Windows_NTnetcoreapp-Windows_NT|AnyCPU.ActiveCfg = netcoreapp-Windows_NT-Debug|Any CPU
|
||||
{6A07CCB8-3E59-47E7-B3DD-DB1F6FC501D5}.DebugNETCoreAppnetcoreapp-Windows_NTnetcoreapp-Windows_NT|AnyCPU.Build.0 = netcoreapp-Windows_NT-Debug|Any CPU
|
||||
{6A07CCB8-3E59-47E7-B3DD-DB1F6FC501D5}.ReleaseNETCoreAppnetcoreapp-Windows_NTnetcoreapp-Windows_NT|AnyCPU.ActiveCfg = netcoreapp-Windows_NT-Release|Any CPU
|
||||
{6A07CCB8-3E59-47E7-B3DD-DB1F6FC501D5}.ReleaseNETCoreAppnetcoreapp-Windows_NTnetcoreapp-Windows_NT|AnyCPU.Build.0 = netcoreapp-Windows_NT-Release|Any CPU
|
||||
{6A07CCB8-3E59-47E7-B3DD-DB1F6FC501D5}.DebugNETCoreAppnetcoreapp-Unixnetcoreapp-Windows_NT|AnyCPU.ActiveCfg = netcoreapp-Unix-Debug|Any CPU
|
||||
{6A07CCB8-3E59-47E7-B3DD-DB1F6FC501D5}.DebugNETCoreAppnetcoreapp-Unixnetcoreapp-Windows_NT|AnyCPU.Build.0 = netcoreapp-Unix-Debug|Any CPU
|
||||
{6A07CCB8-3E59-47E7-B3DD-DB1F6FC501D5}.ReleaseNETCoreAppnetcoreapp-Unixnetcoreapp-Windows_NT|AnyCPU.ActiveCfg = netcoreapp-Unix-Release|Any CPU
|
||||
{6A07CCB8-3E59-47E7-B3DD-DB1F6FC501D5}.ReleaseNETCoreAppnetcoreapp-Unixnetcoreapp-Windows_NT|AnyCPU.Build.0 = netcoreapp-Unix-Release|Any CPU
|
||||
{6A07CCB8-3E59-47E7-B3DD-DB1F6FC501D5}.DebugNETCoreAppnetcoreapp-Unixnetcoreapp-Windows_NT|AnyCPU.ActiveCfg = netcoreapp-Unix-Debug|Any CPU
|
||||
{6A07CCB8-3E59-47E7-B3DD-DB1F6FC501D5}.DebugNETCoreAppnetcoreapp-Unixnetcoreapp-Windows_NT|AnyCPU.Build.0 = netcoreapp-Unix-Debug|Any CPU
|
||||
{6A07CCB8-3E59-47E7-B3DD-DB1F6FC501D5}.ReleaseNETCoreAppnetcoreapp-Unixnetcoreapp-Windows_NT|AnyCPU.ActiveCfg = netcoreapp-Unix-Release|Any CPU
|
||||
{6A07CCB8-3E59-47E7-B3DD-DB1F6FC501D5}.ReleaseNETCoreAppnetcoreapp-Unixnetcoreapp-Windows_NT|AnyCPU.Build.0 = netcoreapp-Unix-Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
8
external/corefx/src/System.Threading.Overlapped/dir.props
vendored
Normal file
8
external/corefx/src/System.Threading.Overlapped/dir.props
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\dir.props" />
|
||||
<PropertyGroup>
|
||||
<AssemblyVersion>4.1.0.0</AssemblyVersion>
|
||||
<IsNETCoreApp>true</IsNETCoreApp>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
9
external/corefx/src/System.Threading.Overlapped/ref/Configurations.props
vendored
Normal file
9
external/corefx/src/System.Threading.Overlapped/ref/Configurations.props
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<BuildConfigurations>
|
||||
netcoreapp;
|
||||
uap;
|
||||
</BuildConfigurations>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
71
external/corefx/src/System.Threading.Overlapped/ref/System.Threading.Overlapped.cs
vendored
Normal file
71
external/corefx/src/System.Threading.Overlapped/ref/System.Threading.Overlapped.cs
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
// ------------------------------------------------------------------------------
|
||||
// Changes to this file must follow the http://aka.ms/api-review process.
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace System.Threading
|
||||
{
|
||||
[System.CLSCompliantAttribute(false)]
|
||||
[System.Security.SecurityCriticalAttribute]
|
||||
public unsafe delegate void IOCompletionCallback(uint errorCode, uint numBytes, System.Threading.NativeOverlapped* pOVERLAP);
|
||||
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
|
||||
public partial struct NativeOverlapped
|
||||
{
|
||||
public System.IntPtr EventHandle;
|
||||
public System.IntPtr InternalHigh;
|
||||
public System.IntPtr InternalLow;
|
||||
public int OffsetHigh;
|
||||
public int OffsetLow;
|
||||
}
|
||||
public sealed partial class PreAllocatedOverlapped : System.IDisposable
|
||||
{
|
||||
[System.CLSCompliantAttribute(false)]
|
||||
public PreAllocatedOverlapped(System.Threading.IOCompletionCallback callback, object state, object pinData) { }
|
||||
public void Dispose() { }
|
||||
}
|
||||
public sealed partial class ThreadPoolBoundHandle : System.IDisposable
|
||||
{
|
||||
internal ThreadPoolBoundHandle() { }
|
||||
public System.Runtime.InteropServices.SafeHandle Handle { get { throw null; } }
|
||||
[System.CLSCompliantAttribute(false)]
|
||||
public unsafe System.Threading.NativeOverlapped* AllocateNativeOverlapped(System.Threading.IOCompletionCallback callback, object state, object pinData) { throw null; }
|
||||
[System.CLSCompliantAttribute(false)]
|
||||
public unsafe System.Threading.NativeOverlapped* AllocateNativeOverlapped(System.Threading.PreAllocatedOverlapped preAllocated) { throw null; }
|
||||
public static System.Threading.ThreadPoolBoundHandle BindHandle(System.Runtime.InteropServices.SafeHandle handle) { throw null; }
|
||||
public void Dispose() { }
|
||||
[System.CLSCompliantAttribute(false)]
|
||||
public unsafe void FreeNativeOverlapped(System.Threading.NativeOverlapped* overlapped) { }
|
||||
[System.CLSCompliantAttribute(false)]
|
||||
public static unsafe object GetNativeOverlappedState(System.Threading.NativeOverlapped* overlapped) { throw null; }
|
||||
}
|
||||
public partial class Overlapped
|
||||
{
|
||||
public Overlapped() { }
|
||||
[System.ObsoleteAttribute("This constructor is not 64-bit compatible. Use the constructor that takes an IntPtr for the event handle. http://go.microsoft.com/fwlink/?linkid=14202")]
|
||||
public Overlapped(int offsetLo, int offsetHi, int hEvent, System.IAsyncResult ar) { }
|
||||
public Overlapped(int offsetLo, int offsetHi, System.IntPtr hEvent, System.IAsyncResult ar) { }
|
||||
public System.IAsyncResult AsyncResult { get { throw null; } set { } }
|
||||
[System.ObsoleteAttribute("This property is not 64-bit compatible. Use EventHandleIntPtr instead. http://go.microsoft.com/fwlink/?linkid=14202")]
|
||||
public int EventHandle { get { throw null; } set { } }
|
||||
public System.IntPtr EventHandleIntPtr { get { throw null; } set { } }
|
||||
public int OffsetHigh { get { throw null; } set { } }
|
||||
public int OffsetLow { get { throw null; } set { } }
|
||||
[System.CLSCompliantAttribute(false)]
|
||||
public static unsafe void Free(System.Threading.NativeOverlapped* nativeOverlappedPtr) { }
|
||||
[System.CLSCompliantAttribute(false)]
|
||||
[System.ObsoleteAttribute("This method is not safe. Use Pack (iocb, userData) instead. http://go.microsoft.com/fwlink/?linkid=14202")]
|
||||
public unsafe System.Threading.NativeOverlapped* Pack(System.Threading.IOCompletionCallback iocb) { throw null; }
|
||||
[System.CLSCompliantAttribute(false)]
|
||||
public unsafe System.Threading.NativeOverlapped* Pack(System.Threading.IOCompletionCallback iocb, object userData) { throw null; }
|
||||
[System.CLSCompliantAttribute(false)]
|
||||
public static unsafe System.Threading.Overlapped Unpack(System.Threading.NativeOverlapped* nativeOverlappedPtr) { throw null; }
|
||||
[System.CLSCompliantAttribute(false)]
|
||||
[System.ObsoleteAttribute("This method is not safe. Use UnsafePack (iocb, userData) instead. http://go.microsoft.com/fwlink/?linkid=14202")]
|
||||
public unsafe System.Threading.NativeOverlapped* UnsafePack(System.Threading.IOCompletionCallback iocb) { throw null; }
|
||||
[System.CLSCompliantAttribute(false)]
|
||||
public unsafe System.Threading.NativeOverlapped* UnsafePack(System.Threading.IOCompletionCallback iocb, object userData) { throw null; }
|
||||
}
|
||||
}
|
||||
18
external/corefx/src/System.Threading.Overlapped/ref/System.Threading.Overlapped.csproj
vendored
Normal file
18
external/corefx/src/System.Threading.Overlapped/ref/System.Threading.Overlapped.csproj
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
|
||||
<PropertyGroup>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Debug|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Release|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap-Debug|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap-Release|AnyCPU'" />
|
||||
<ItemGroup>
|
||||
<Compile Include="System.Threading.Overlapped.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\System.Runtime\ref\System.Runtime.csproj" />
|
||||
</ItemGroup>
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
|
||||
</Project>
|
||||
10
external/corefx/src/System.Threading.Overlapped/src/Configurations.props
vendored
Normal file
10
external/corefx/src/System.Threading.Overlapped/src/Configurations.props
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<BuildConfigurations>
|
||||
net463-Windows_NT;
|
||||
netcoreapp-Windows_NT;
|
||||
netcoreapp-Unix;
|
||||
</BuildConfigurations>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
138
external/corefx/src/System.Threading.Overlapped/src/Resources/Strings.resx
vendored
Normal file
138
external/corefx/src/System.Threading.Overlapped/src/Resources/Strings.resx
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="Argument_AlreadyBoundOrSyncHandle" xml:space="preserve">
|
||||
<value>'handle' has already been bound to the thread pool, or was not opened for asynchronous I/O.</value>
|
||||
</data>
|
||||
<data name="Argument_InvalidHandle" xml:space="preserve">
|
||||
<value>'handle' has been disposed or is an invalid handle.</value>
|
||||
</data>
|
||||
<data name="Argument_NativeOverlappedAlreadyFree" xml:space="preserve">
|
||||
<value>'overlapped' has already been freed.</value>
|
||||
</data>
|
||||
<data name="Argument_NativeOverlappedWrongBoundHandle" xml:space="preserve">
|
||||
<value>'overlapped' was not allocated by this ThreadPoolBoundHandle instance.</value>
|
||||
</data>
|
||||
<data name="Argument_PreAllocatedAlreadyAllocated" xml:space="preserve">
|
||||
<value>'preAllocated' is already in use.</value>
|
||||
</data>
|
||||
<data name="InvalidOperation_NativeOverlappedReused" xml:space="preserve">
|
||||
<value>NativeOverlapped cannot be reused for multiple operations.</value>
|
||||
</data>
|
||||
</root>
|
||||
70
external/corefx/src/System.Threading.Overlapped/src/System.Threading.Overlapped.csproj
vendored
Normal file
70
external/corefx/src/System.Threading.Overlapped/src/System.Threading.Overlapped.csproj
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
|
||||
<PropertyGroup>
|
||||
<AssemblyName>System.Threading.Overlapped</AssemblyName>
|
||||
<ProjectGuid>{6A07CCB8-3E59-47e7-B3DD-DB1F6FC501D5}</ProjectGuid>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<IsPartialFacadeAssembly Condition="'$(TargetsWindows)' == 'true'">true</IsPartialFacadeAssembly>
|
||||
<GeneratePlatformNotSupportedAssembly Condition="'$(TargetsUnix)' == 'true'">true</GeneratePlatformNotSupportedAssembly>
|
||||
</PropertyGroup>
|
||||
<!-- Help VS understand available configurations -->
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='net463-Windows_NT-Debug|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='net463-Windows_NT-Release|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='netcoreapp-Windows_NT-Debug|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='netcoreapp-Windows_NT-Release|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='netcoreapp-Unix-Debug|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='netcoreapp-Unix-Release|AnyCPU'" />
|
||||
<ItemGroup Condition="'$(TargetGroup)'=='netcoreapp' AND '$(TargetsWindows)' == 'true'">
|
||||
<ProjectReference Include="..\..\System.Diagnostics.Debug\src\System.Diagnostics.Debug.csproj">
|
||||
<Project>{E7E8DE8A-9EC1-46A8-A6EE-727DB32DBEB8}</Project>
|
||||
<Name>System.Diagnostics.Debug</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(TargetsUnix)' != 'true'">
|
||||
<Compile Include="System\Threading\DeferredDisposableLifetime.cs" />
|
||||
<Compile Include="$(CommonPath)\System\HResults.cs">
|
||||
<Link>Common\System\HResults.cs</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="('$(TargetGroup)'=='netcoreapp' AND '$(TargetsWindows)' == 'true') OR '$(TargetGroup)'=='net463'">
|
||||
<Compile Include="System\Threading\ClrThreadPoolBoundHandle.cs" />
|
||||
<Compile Include="System\Threading\ClrThreadPoolBoundHandleOverlapped.cs" />
|
||||
<Compile Include="System\Threading\ClrThreadPoolPreAllocatedOverlapped.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(TargetGroup)'=='net463'">
|
||||
<TargetingPackReference Include="mscorlib" />
|
||||
<TargetingPackReference Include="System" />
|
||||
<Compile Include="$(CommonPath)\System\NotImplemented.cs">
|
||||
<Link>Common\NotImplemented.cs</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(TargetGroup)'=='netcoreapp' AND '$(TargetsWindows)' == 'true'">
|
||||
<TargetingPackReference Include="System.Private.CoreLib" />
|
||||
<ReferenceFromRuntime Include="System.Private.CoreLib" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(TargetGroup)'=='netcoreapp' AND '$(TargetsWindows)' != 'true'">
|
||||
<Reference Include="System.Resources.ResourceManager" />
|
||||
<Reference Include="System.Runtime" />
|
||||
<Reference Include="System.Runtime.Handles" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(TargetGroup)'=='netcore50'">
|
||||
<Compile Include="$(CommonPath)\Interop\Windows\Interop.Libraries.cs">
|
||||
<Link>Common\Interop\Interop.Libraries.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\Interop\Windows\kernel32\Interop.ThreadPoolIO.cs">
|
||||
<Link>Common\Interop\Interop.ThreadPoolIO.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\Microsoft\Win32\SafeHandles\SafeThreadPoolIOHandle.cs">
|
||||
<Link>Microsoft\Win32\SafeHandles\SafeThreadPoolIOHandle.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="System\Threading\IOCompletionCallback.cs" />
|
||||
<Compile Include="System\Threading\NativeOverlapped.cs" />
|
||||
<Compile Include="System\Threading\Win32ThreadPoolBoundHandle.cs" />
|
||||
<Compile Include="System\Threading\Win32ThreadPoolNativeOverlapped.ExecutionContextCallbackArgs.cs" />
|
||||
<Compile Include="System\Threading\Win32ThreadPoolNativeOverlapped.OverlappedData.cs" />
|
||||
<Compile Include="System\Threading\Win32ThreadPoolNativeOverlapped.cs" />
|
||||
<Compile Include="System\Threading\Win32ThreadPoolPreAllocatedOverlapped.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
|
||||
</Project>
|
||||
319
external/corefx/src/System.Threading.Overlapped/src/System/Threading/ClrThreadPoolBoundHandle.cs
vendored
Normal file
319
external/corefx/src/System.Threading.Overlapped/src/System/Threading/ClrThreadPoolBoundHandle.cs
vendored
Normal file
@@ -0,0 +1,319 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace System.Threading
|
||||
{
|
||||
//
|
||||
// Implementation of ThreadPoolBoundHandle that sits on top of the CLR's ThreadPool and Overlapped infrastructure
|
||||
//
|
||||
|
||||
/// <summary>
|
||||
/// Represents an I/O handle that is bound to the system thread pool and enables low-level
|
||||
/// components to receive notifications for asynchronous I/O operations.
|
||||
/// </summary>
|
||||
public sealed partial class ThreadPoolBoundHandle : IDisposable
|
||||
{
|
||||
private readonly SafeHandle _handle;
|
||||
private bool _isDisposed;
|
||||
|
||||
private ThreadPoolBoundHandle(SafeHandle handle)
|
||||
{
|
||||
_handle = handle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the bound operating system handle.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="SafeHandle"/> object that holds the bound operating system handle.
|
||||
/// </value>
|
||||
public SafeHandle Handle
|
||||
{
|
||||
get { return _handle; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="ThreadPoolBoundHandle"/> for the specific handle,
|
||||
/// which is bound to the system thread pool.
|
||||
/// </summary>
|
||||
/// <param name="handle">
|
||||
/// A <see cref="SafeHandle"/> object that holds the operating system handle. The
|
||||
/// handle must have been opened for overlapped I/O on the unmanaged side.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see cref="ThreadPoolBoundHandle"/> for <paramref name="handle"/>, which
|
||||
/// is bound to the system thread pool.
|
||||
/// </returns>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="handle"/> is <see langword="null"/>.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <paramref name="handle"/> has been disposed.
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <paramref name="handle"/> does not refer to a valid I/O handle.
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <paramref name="handle"/> refers to a handle that has not been opened
|
||||
/// for overlapped I/O.
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <paramref name="handle"/> refers to a handle that has already been bound.
|
||||
/// </exception>
|
||||
/// <remarks>
|
||||
/// This method should be called once per handle.
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <see cref="ThreadPoolBoundHandle"/> does not take ownership of <paramref name="handle"/>,
|
||||
/// it remains the responsibility of the caller to call <see cref="SafeHandle.Dispose"/>.
|
||||
/// </remarks>
|
||||
public static ThreadPoolBoundHandle BindHandle(SafeHandle handle)
|
||||
{
|
||||
if (handle == null)
|
||||
throw new ArgumentNullException(nameof(handle));
|
||||
|
||||
if (handle.IsClosed || handle.IsInvalid)
|
||||
throw new ArgumentException(SR.Argument_InvalidHandle, nameof(handle));
|
||||
|
||||
try
|
||||
{
|
||||
// ThreadPool.BindHandle will always return true, otherwise, it throws. See the underlying FCall
|
||||
// implementation in ThreadPoolNative::CorBindIoCompletionCallback to see the implementation.
|
||||
bool succeeded = ThreadPool.BindHandle(handle);
|
||||
Debug.Assert(succeeded);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{ // BindHandle throws ApplicationException on full CLR and Exception on CoreCLR.
|
||||
// We do not let either of these leak and convert them to ArgumentException to
|
||||
// indicate that the specified handles are invalid.
|
||||
|
||||
if (ex.HResult == System.HResults.E_HANDLE) // Bad handle
|
||||
throw new ArgumentException(SR.Argument_InvalidHandle, nameof(handle));
|
||||
|
||||
if (ex.HResult == System.HResults.E_INVALIDARG) // Handle already bound or sync handle
|
||||
throw new ArgumentException(SR.Argument_AlreadyBoundOrSyncHandle, nameof(handle));
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
return new ThreadPoolBoundHandle(handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an unmanaged pointer to a <see cref="NativeOverlapped"/> structure, specifying
|
||||
/// a delegate that is invoked when the asynchronous I/O operation is complete, a user-provided
|
||||
/// object providing context, and managed objects that serve as buffers.
|
||||
/// </summary>
|
||||
/// <param name="callback">
|
||||
/// An <see cref="IOCompletionCallback"/> delegate that represents the callback method
|
||||
/// invoked when the asynchronous I/O operation completes.
|
||||
/// </param>
|
||||
/// <param name="state">
|
||||
/// A user-provided object that distinguishes this <see cref="NativeOverlapped"/> from other
|
||||
/// <see cref="NativeOverlapped"/> instances. Can be <see langword="null"/>.
|
||||
/// </param>
|
||||
/// <param name="pinData">
|
||||
/// An object or array of objects representing the input or output buffer for the operation. Each
|
||||
/// object represents a buffer, for example an array of bytes. Can be <see langword="null"/>.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// An unmanaged pointer to a <see cref="NativeOverlapped"/> structure.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// The unmanaged pointer returned by this method can be passed to the operating system in
|
||||
/// overlapped I/O operations. The <see cref="NativeOverlapped"/> structure is fixed in
|
||||
/// physical memory until <see cref="FreeNativeOverlapped(NativeOverlapped*)"/> is called.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The buffer or buffers specified in <paramref name="pinData"/> must be the same as those passed
|
||||
/// to the unmanaged operating system function that performs the asynchronous I/O.
|
||||
/// </para>
|
||||
/// <note>
|
||||
/// The buffers specified in <paramref name="pinData"/> are pinned for the duration of
|
||||
/// the I/O operation.
|
||||
/// </note>
|
||||
/// </remarks>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="callback"/> is <see langword="null"/>.
|
||||
/// </exception>
|
||||
/// <exception cref="ObjectDisposedException">
|
||||
/// This method was called after the <see cref="ThreadPoolBoundHandle"/> was disposed.
|
||||
/// </exception>
|
||||
[CLSCompliant(false)]
|
||||
public unsafe NativeOverlapped* AllocateNativeOverlapped(IOCompletionCallback callback, object state, object pinData)
|
||||
{
|
||||
if (callback == null)
|
||||
throw new ArgumentNullException(nameof(callback));
|
||||
|
||||
EnsureNotDisposed();
|
||||
|
||||
ThreadPoolBoundHandleOverlapped overlapped = new ThreadPoolBoundHandleOverlapped(callback, state, pinData, preAllocated: null);
|
||||
overlapped._boundHandle = this;
|
||||
return overlapped._nativeOverlapped;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an unmanaged pointer to a <see cref="NativeOverlapped"/> structure, using the callback,
|
||||
/// state, and buffers associated with the specified <see cref="PreAllocatedOverlapped"/> object.
|
||||
/// </summary>
|
||||
/// <param name="preAllocated">
|
||||
/// A <see cref="PreAllocatedOverlapped"/> object from which to create the NativeOverlapped pointer.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// An unmanaged pointer to a <see cref="NativeOverlapped"/> structure.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// The unmanaged pointer returned by this method can be passed to the operating system in
|
||||
/// overlapped I/O operations. The <see cref="NativeOverlapped"/> structure is fixed in
|
||||
/// physical memory until <see cref="FreeNativeOverlapped(NativeOverlapped*)"/> is called.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="preAllocated"/> is <see langword="null"/>.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <paramref name="preAllocated"/> is currently in use for another I/O operation.
|
||||
/// </exception>
|
||||
/// <exception cref="ObjectDisposedException">
|
||||
/// This method was called after the <see cref="ThreadPoolBoundHandle"/> was disposed, or
|
||||
/// this method was called after <paramref name="preAllocated"/> was disposed.
|
||||
/// </exception>
|
||||
/// <seealso cref="PreAllocatedOverlapped"/>
|
||||
[CLSCompliant(false)]
|
||||
public unsafe NativeOverlapped* AllocateNativeOverlapped(PreAllocatedOverlapped preAllocated)
|
||||
{
|
||||
if (preAllocated == null)
|
||||
throw new ArgumentNullException(nameof(preAllocated));
|
||||
|
||||
EnsureNotDisposed();
|
||||
|
||||
preAllocated.AddRef();
|
||||
try
|
||||
{
|
||||
ThreadPoolBoundHandleOverlapped overlapped = preAllocated._overlapped;
|
||||
|
||||
if (overlapped._boundHandle != null)
|
||||
throw new ArgumentException(SR.Argument_PreAllocatedAlreadyAllocated, nameof(preAllocated));
|
||||
|
||||
overlapped._boundHandle = this;
|
||||
|
||||
return overlapped._nativeOverlapped;
|
||||
}
|
||||
catch
|
||||
{
|
||||
preAllocated.Release();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Frees the unmanaged memory associated with a <see cref="NativeOverlapped"/> structure
|
||||
/// allocated by the <see cref="AllocateNativeOverlapped"/> method.
|
||||
/// </summary>
|
||||
/// <param name="overlapped">
|
||||
/// An unmanaged pointer to the <see cref="NativeOverlapped"/> structure to be freed.
|
||||
/// </param>
|
||||
/// <remarks>
|
||||
/// <note type="caution">
|
||||
/// You must call the <see cref="FreeNativeOverlapped(NativeOverlapped*)"/> method exactly once
|
||||
/// on every <see cref="NativeOverlapped"/> unmanaged pointer allocated using the
|
||||
/// <see cref="AllocateNativeOverlapped"/> method.
|
||||
/// If you do not call the <see cref="FreeNativeOverlapped(NativeOverlapped*)"/> method, you will
|
||||
/// leak memory. If you call the <see cref="FreeNativeOverlapped(NativeOverlapped*)"/> method more
|
||||
/// than once on the same <see cref="NativeOverlapped"/> unmanaged pointer, memory will be corrupted.
|
||||
/// </note>
|
||||
/// </remarks>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="overlapped"/> is <see langword="null"/>.
|
||||
/// </exception>
|
||||
/// <exception cref="ObjectDisposedException">
|
||||
/// This method was called after the <see cref="ThreadPoolBoundHandle"/> was disposed.
|
||||
/// </exception>
|
||||
[CLSCompliant(false)]
|
||||
public unsafe void FreeNativeOverlapped(NativeOverlapped* overlapped)
|
||||
{
|
||||
if (overlapped == null)
|
||||
throw new ArgumentNullException(nameof(overlapped));
|
||||
|
||||
// Note: we explicitly allow FreeNativeOverlapped calls after the ThreadPoolBoundHandle has been Disposed.
|
||||
|
||||
ThreadPoolBoundHandleOverlapped wrapper = GetOverlappedWrapper(overlapped, this);
|
||||
|
||||
if (wrapper._boundHandle != this)
|
||||
throw new ArgumentException(SR.Argument_NativeOverlappedWrongBoundHandle, nameof(overlapped));
|
||||
|
||||
if (wrapper._preAllocated != null)
|
||||
wrapper._preAllocated.Release();
|
||||
else
|
||||
Overlapped.Free(overlapped);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the user-provided object specified when the <see cref="NativeOverlapped"/> instance was
|
||||
/// allocated using the <see cref="AllocateNativeOverlapped(IOCompletionCallback, object, byte[])"/>.
|
||||
/// </summary>
|
||||
/// <param name="overlapped">
|
||||
/// An unmanaged pointer to the <see cref="NativeOverlapped"/> structure from which to return the
|
||||
/// asscociated user-provided object.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A user-provided object that distinguishes this <see cref="NativeOverlapped"/>
|
||||
/// from other <see cref="NativeOverlapped"/> instances, otherwise, <see langword="null"/> if one was
|
||||
/// not specified when the instance was allocated using <see cref="AllocateNativeOverlapped"/>.
|
||||
/// </returns>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="overlapped"/> is <see langword="null"/>.
|
||||
/// </exception>
|
||||
[CLSCompliant(false)]
|
||||
public static unsafe object GetNativeOverlappedState(NativeOverlapped* overlapped)
|
||||
{
|
||||
if (overlapped == null)
|
||||
throw new ArgumentNullException(nameof(overlapped));
|
||||
|
||||
ThreadPoolBoundHandleOverlapped wrapper = GetOverlappedWrapper(overlapped, null);
|
||||
Debug.Assert(wrapper._boundHandle != null);
|
||||
return wrapper._userState;
|
||||
}
|
||||
|
||||
private static unsafe ThreadPoolBoundHandleOverlapped GetOverlappedWrapper(NativeOverlapped* overlapped, ThreadPoolBoundHandle expectedBoundHandle)
|
||||
{
|
||||
ThreadPoolBoundHandleOverlapped wrapper;
|
||||
try
|
||||
{
|
||||
wrapper = (ThreadPoolBoundHandleOverlapped)Overlapped.Unpack(overlapped);
|
||||
}
|
||||
catch (NullReferenceException ex)
|
||||
{
|
||||
throw new ArgumentException(SR.Argument_NativeOverlappedAlreadyFree, nameof(overlapped), ex);
|
||||
}
|
||||
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// .NET Native's version of ThreadPoolBoundHandle that wraps the Win32 ThreadPool holds onto
|
||||
// native resources so it needs to be disposable. To match the contract, we are also disposable.
|
||||
// We also implement a disposable state to mimic behavior between this implementation and
|
||||
// .NET Native's version (code written against us, will also work against .NET Native's version).
|
||||
_isDisposed = true;
|
||||
}
|
||||
|
||||
|
||||
private void EnsureNotDisposed()
|
||||
{
|
||||
if (_isDisposed)
|
||||
throw new ObjectDisposedException(GetType().ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace System.Threading
|
||||
{
|
||||
/// <summary>
|
||||
/// Overlapped subclass adding data needed by ThreadPoolBoundHandle.
|
||||
/// </summary>
|
||||
internal sealed class ThreadPoolBoundHandleOverlapped : Overlapped
|
||||
{
|
||||
private static readonly unsafe IOCompletionCallback s_completionCallback = CompletionCallback;
|
||||
|
||||
private readonly IOCompletionCallback _userCallback;
|
||||
internal readonly object _userState;
|
||||
internal PreAllocatedOverlapped _preAllocated;
|
||||
internal unsafe NativeOverlapped* _nativeOverlapped;
|
||||
internal ThreadPoolBoundHandle _boundHandle;
|
||||
internal bool _completed;
|
||||
|
||||
public unsafe ThreadPoolBoundHandleOverlapped(IOCompletionCallback callback, object state, object pinData, PreAllocatedOverlapped preAllocated)
|
||||
{
|
||||
_userCallback = callback;
|
||||
_userState = state;
|
||||
_preAllocated = preAllocated;
|
||||
|
||||
_nativeOverlapped = Pack(s_completionCallback, pinData);
|
||||
_nativeOverlapped->OffsetLow = 0; // CLR reuses NativeOverlapped instances and does not reset these
|
||||
_nativeOverlapped->OffsetHigh = 0;
|
||||
}
|
||||
|
||||
private static unsafe void CompletionCallback(uint errorCode, uint numBytes, NativeOverlapped* nativeOverlapped)
|
||||
{
|
||||
ThreadPoolBoundHandleOverlapped overlapped = (ThreadPoolBoundHandleOverlapped)Overlapped.Unpack(nativeOverlapped);
|
||||
|
||||
//
|
||||
// The Win32 thread pool implementation of ThreadPoolBoundHandle does not permit reuse of NativeOverlapped
|
||||
// pointers without freeing them and allocating new a new one. We need to ensure that code using the CLR
|
||||
// ThreadPool implementation follows those rules.
|
||||
//
|
||||
if (overlapped._completed)
|
||||
throw new InvalidOperationException(SR.InvalidOperation_NativeOverlappedReused);
|
||||
|
||||
overlapped._completed = true;
|
||||
|
||||
if (overlapped._boundHandle == null)
|
||||
throw new InvalidOperationException(SR.Argument_NativeOverlappedAlreadyFree);
|
||||
|
||||
overlapped._userCallback(errorCode, numBytes, nativeOverlapped);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace System.Threading
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents pre-allocated state for native overlapped I/O operations.
|
||||
/// </summary>
|
||||
/// <seealso cref="ThreadPoolBoundHandle.AllocateNativeOverlapped(PreAllocatedOverlapped)"/>
|
||||
public sealed class PreAllocatedOverlapped : IDisposable, IDeferredDisposable
|
||||
{
|
||||
internal readonly ThreadPoolBoundHandleOverlapped _overlapped;
|
||||
private DeferredDisposableLifetime<PreAllocatedOverlapped> _lifetime;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PreAllocatedOverlapped"/> class, specifying
|
||||
/// a delegate that is invoked when each asynchronous I/O operation is complete, a user-provided
|
||||
/// object providing context, and managed objects that serve as buffers.
|
||||
/// </summary>
|
||||
/// <param name="callback">
|
||||
/// An <see cref="IOCompletionCallback"/> delegate that represents the callback method
|
||||
/// invoked when each asynchronous I/O operation completes.
|
||||
/// </param>
|
||||
/// <param name="state">
|
||||
/// A user-provided object that distinguishes <see cref="NativeOverlapped"/> instance produced from this
|
||||
/// object from other <see cref="NativeOverlapped"/> instances. Can be <see langword="null"/>.
|
||||
/// </param>
|
||||
/// <param name="pinData">
|
||||
/// An object or array of objects representing the input or output buffer for the operations. Each
|
||||
/// object represents a buffer, for example an array of bytes. Can be <see langword="null"/>.
|
||||
/// </param>
|
||||
/// <remarks>
|
||||
/// The new <see cref="PreAllocatedOverlapped"/> instance can be passed to
|
||||
/// <see cref="ThreadPoolBoundHandle.AllocateNativeOverlapped(PreAllocatedOverlapped)"/>, to produce
|
||||
/// a <see cref="NativeOverlapped"/> instance that can be passed to the operating system in overlapped
|
||||
/// I/O operations. A single <see cref="PreAllocatedOverlapped"/> instance can only be used for
|
||||
/// a single native I/O operation at a time. However, the state stored in the <see cref="PreAllocatedOverlapped"/>
|
||||
/// instance can be reused for subsequent native operations.
|
||||
/// <note>
|
||||
/// The buffers specified in <paramref name="pinData"/> are pinned until <see cref="Dispose"/> is called.
|
||||
/// </note>
|
||||
/// </remarks>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="callback"/> is <see langword="null"/>.
|
||||
/// </exception>
|
||||
/// <exception cref="ObjectDisposedException">
|
||||
/// This method was called after the <see cref="ThreadPoolBoundHandle"/> was disposed.
|
||||
/// </exception>
|
||||
[CLSCompliant(false)]
|
||||
public unsafe PreAllocatedOverlapped(IOCompletionCallback callback, object state, object pinData)
|
||||
{
|
||||
if (callback == null)
|
||||
throw new ArgumentNullException(nameof(callback));
|
||||
|
||||
_overlapped = new ThreadPoolBoundHandleOverlapped(callback, state, pinData, this);
|
||||
}
|
||||
|
||||
internal bool AddRef()
|
||||
{
|
||||
return _lifetime.AddRef(this);
|
||||
}
|
||||
|
||||
internal void Release()
|
||||
{
|
||||
_lifetime.Release(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Frees the resources associated with this <see cref="PreAllocatedOverlapped"/> instance.
|
||||
/// </summary>
|
||||
public unsafe void Dispose()
|
||||
{
|
||||
_lifetime.Dispose(this);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
~PreAllocatedOverlapped()
|
||||
{
|
||||
//
|
||||
// During shutdown, don't automatically clean up, because this instance may still be
|
||||
// reachable/usable by other code.
|
||||
//
|
||||
if (!Environment.HasShutdownStarted)
|
||||
Dispose();
|
||||
}
|
||||
|
||||
unsafe void IDeferredDisposable.OnFinalRelease(bool disposed)
|
||||
{
|
||||
if (_overlapped != null)
|
||||
{
|
||||
if (disposed)
|
||||
{
|
||||
Overlapped.Free(_overlapped._nativeOverlapped);
|
||||
}
|
||||
else
|
||||
{
|
||||
_overlapped._boundHandle = null;
|
||||
_overlapped._completed = false;
|
||||
*_overlapped._nativeOverlapped = default(NativeOverlapped);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
116
external/corefx/src/System.Threading.Overlapped/src/System/Threading/DeferredDisposableLifetime.cs
vendored
Normal file
116
external/corefx/src/System.Threading.Overlapped/src/System/Threading/DeferredDisposableLifetime.cs
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace System.Threading
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides callbacks to objects whose lifetime is managed by <see cref="DeferredDisposableLifetime{T}"/>.
|
||||
/// </summary>
|
||||
internal interface IDeferredDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Called when the object's refcount reaches zero.
|
||||
/// </summary>
|
||||
/// <param name="disposed">
|
||||
/// Indicates whether the object has been disposed.
|
||||
/// </param>
|
||||
/// <remarks>
|
||||
/// If the refount reaches zero before the object is disposed, this method will be called with
|
||||
/// <paramref name="disposed"/> set to false. If the object is then disposed, this method will be
|
||||
/// called again, with <paramref name="disposed"/> set to true. If the refcount reaches zero
|
||||
/// after the object has already been disposed, this will be called a single time, with
|
||||
/// <paramref name="disposed"/> set to true.
|
||||
/// </remarks>
|
||||
void OnFinalRelease(bool disposed);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Manages the lifetime of an object which implements IDisposable, but which must defer the actual
|
||||
/// cleanup of state until all existing uses of the object are complete.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of object whose lifetime will be managed.</typeparam>
|
||||
/// <remarks>
|
||||
/// This type maintains a reference count, and tracks whether the object has been disposed. When
|
||||
/// Callbacks are made to <see cref="IDeferredDisposable.OnFinalRelease(bool)"/> when the refcount
|
||||
/// reaches zero. Objects that need to defer cleanup until they have been disposed *and* they have
|
||||
/// no more references can do so in <see cref="IDeferredDisposable.OnFinalRelease(bool)"/> when
|
||||
/// 'disposed' is true.
|
||||
/// </remarks>
|
||||
internal struct DeferredDisposableLifetime<T> where T : class, IDeferredDisposable
|
||||
{
|
||||
//
|
||||
// _count is positive until Dispose is called, after which it's (-1 - refcount).
|
||||
//
|
||||
private int _count;
|
||||
|
||||
public bool AddRef(T obj)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
int oldCount = Volatile.Read(ref _count);
|
||||
|
||||
// Have we been disposed?
|
||||
if (oldCount < 0)
|
||||
throw new ObjectDisposedException(typeof(T).ToString());
|
||||
|
||||
int newCount = checked(oldCount + 1);
|
||||
|
||||
if (Interlocked.CompareExchange(ref _count, newCount, oldCount) == oldCount)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Release(T obj)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
int oldCount = Volatile.Read(ref _count);
|
||||
if (oldCount > 0)
|
||||
{
|
||||
// We haven't been disposed. Decrement _count.
|
||||
int newCount = oldCount - 1;
|
||||
if (Interlocked.CompareExchange(ref _count, newCount, oldCount) == oldCount)
|
||||
{
|
||||
if (newCount == 0)
|
||||
obj.OnFinalRelease(disposed: false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Assert(oldCount != 0 && oldCount != -1);
|
||||
|
||||
// We've been disposed. Increment _count.
|
||||
int newCount = oldCount + 1;
|
||||
if (Interlocked.CompareExchange(ref _count, newCount, oldCount) == oldCount)
|
||||
{
|
||||
if (newCount == -1)
|
||||
obj.OnFinalRelease(disposed: true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose(T obj)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
int oldCount = Volatile.Read(ref _count);
|
||||
if (oldCount < 0)
|
||||
return; // already disposed
|
||||
|
||||
int newCount = -1 - oldCount;
|
||||
if (Interlocked.CompareExchange(ref _count, newCount, oldCount) == oldCount)
|
||||
{
|
||||
if (newCount == -1)
|
||||
obj.OnFinalRelease(disposed: true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
9
external/corefx/src/System.Threading.Overlapped/src/System/Threading/IOCompletionCallback.cs
vendored
Normal file
9
external/corefx/src/System.Threading.Overlapped/src/System/Threading/IOCompletionCallback.cs
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace System.Threading
|
||||
{
|
||||
[CLSCompliant(false)]
|
||||
public unsafe delegate void IOCompletionCallback(uint errorCode, uint numBytes, NativeOverlapped* pOVERLAP);
|
||||
}
|
||||
18
external/corefx/src/System.Threading.Overlapped/src/System/Threading/NativeOverlapped.cs
vendored
Normal file
18
external/corefx/src/System.Threading.Overlapped/src/System/Threading/NativeOverlapped.cs
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace System.Threading
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct NativeOverlapped
|
||||
{
|
||||
public IntPtr InternalLow;
|
||||
public IntPtr InternalHigh;
|
||||
public int OffsetLow;
|
||||
public int OffsetHigh;
|
||||
public IntPtr EventHandle;
|
||||
}
|
||||
}
|
||||
213
external/corefx/src/System.Threading.Overlapped/src/System/Threading/Win32ThreadPoolBoundHandle.cs
vendored
Normal file
213
external/corefx/src/System.Threading.Overlapped/src/System/Threading/Win32ThreadPoolBoundHandle.cs
vendored
Normal file
@@ -0,0 +1,213 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
|
||||
namespace System.Threading
|
||||
{
|
||||
//
|
||||
// Implementation of ThreadPoolBoundHandle that sits on top of the Win32 ThreadPool
|
||||
//
|
||||
public sealed class ThreadPoolBoundHandle : IDisposable, IDeferredDisposable
|
||||
{
|
||||
private static Interop.NativeIoCompletionCallback s_nativeIoCompletionCallback;
|
||||
private readonly SafeHandle _handle;
|
||||
private readonly SafeThreadPoolIOHandle _threadPoolHandle;
|
||||
private DeferredDisposableLifetime<ThreadPoolBoundHandle> _lifetime;
|
||||
|
||||
private ThreadPoolBoundHandle(SafeHandle handle, SafeThreadPoolIOHandle threadPoolHandle)
|
||||
{
|
||||
_threadPoolHandle = threadPoolHandle;
|
||||
_handle = handle;
|
||||
}
|
||||
|
||||
public SafeHandle Handle
|
||||
{
|
||||
get { return _handle; }
|
||||
}
|
||||
|
||||
public static ThreadPoolBoundHandle BindHandle(SafeHandle handle)
|
||||
{
|
||||
if (handle == null)
|
||||
throw new ArgumentNullException(nameof(handle));
|
||||
|
||||
if (handle.IsClosed || handle.IsInvalid)
|
||||
throw new ArgumentException(SR.Argument_InvalidHandle, nameof(handle));
|
||||
|
||||
// Make sure we use a statically-rooted completion callback,
|
||||
// so it doesn't get collected while the I/O is in progress.
|
||||
Interop.NativeIoCompletionCallback callback = s_nativeIoCompletionCallback;
|
||||
if (callback == null)
|
||||
s_nativeIoCompletionCallback = callback = new Interop.NativeIoCompletionCallback(OnNativeIOCompleted);
|
||||
|
||||
SafeThreadPoolIOHandle threadPoolHandle = Interop.Kernel32.CreateThreadpoolIo(handle, s_nativeIoCompletionCallback, IntPtr.Zero, IntPtr.Zero);
|
||||
if (threadPoolHandle.IsInvalid)
|
||||
{
|
||||
int hr = Marshal.GetHRForLastWin32Error();
|
||||
if (hr == System.HResults.E_HANDLE) // Bad handle
|
||||
throw new ArgumentException(SR.Argument_InvalidHandle, nameof(handle));
|
||||
|
||||
if (hr == System.HResults.E_INVALIDARG) // Handle already bound or sync handle
|
||||
throw new ArgumentException(SR.Argument_AlreadyBoundOrSyncHandle, nameof(handle));
|
||||
|
||||
throw Marshal.GetExceptionForHR(hr, new IntPtr(-1));
|
||||
}
|
||||
|
||||
return new ThreadPoolBoundHandle(handle, threadPoolHandle);
|
||||
}
|
||||
|
||||
[CLSCompliant(false)]
|
||||
public unsafe NativeOverlapped* AllocateNativeOverlapped(IOCompletionCallback callback, object state, object pinData)
|
||||
{
|
||||
if (callback == null)
|
||||
throw new ArgumentNullException(nameof(callback));
|
||||
|
||||
AddRef();
|
||||
try
|
||||
{
|
||||
Win32ThreadPoolNativeOverlapped* overlapped = Win32ThreadPoolNativeOverlapped.Allocate(callback, state, pinData, preAllocated: null);
|
||||
overlapped->Data._boundHandle = this;
|
||||
|
||||
Interop.Kernel32.StartThreadpoolIo(_threadPoolHandle);
|
||||
|
||||
return Win32ThreadPoolNativeOverlapped.ToNativeOverlapped(overlapped);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Release();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
[CLSCompliant(false)]
|
||||
public unsafe NativeOverlapped* AllocateNativeOverlapped(PreAllocatedOverlapped preAllocated)
|
||||
{
|
||||
if (preAllocated == null)
|
||||
throw new ArgumentNullException(nameof(preAllocated));
|
||||
|
||||
bool addedRefToThis = false;
|
||||
bool addedRefToPreAllocated = false;
|
||||
try
|
||||
{
|
||||
addedRefToThis = AddRef();
|
||||
addedRefToPreAllocated = preAllocated.AddRef();
|
||||
|
||||
Win32ThreadPoolNativeOverlapped.OverlappedData data = preAllocated._overlapped->Data;
|
||||
if (data._boundHandle != null)
|
||||
throw new ArgumentException(SR.Argument_PreAllocatedAlreadyAllocated, nameof(preAllocated));
|
||||
|
||||
data._boundHandle = this;
|
||||
|
||||
Interop.Kernel32.StartThreadpoolIo(_threadPoolHandle);
|
||||
|
||||
return Win32ThreadPoolNativeOverlapped.ToNativeOverlapped(preAllocated._overlapped);
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (addedRefToPreAllocated)
|
||||
preAllocated.Release();
|
||||
if (addedRefToThis)
|
||||
Release();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
[CLSCompliant(false)]
|
||||
public unsafe void FreeNativeOverlapped(NativeOverlapped* overlapped)
|
||||
{
|
||||
if (overlapped == null)
|
||||
throw new ArgumentNullException(nameof(overlapped));
|
||||
|
||||
Win32ThreadPoolNativeOverlapped* threadPoolOverlapped = Win32ThreadPoolNativeOverlapped.FromNativeOverlapped(overlapped);
|
||||
Win32ThreadPoolNativeOverlapped.OverlappedData data = GetOverlappedData(threadPoolOverlapped, this);
|
||||
|
||||
if (!data._completed)
|
||||
{
|
||||
Interop.Kernel32.CancelThreadpoolIo(_threadPoolHandle);
|
||||
Release();
|
||||
}
|
||||
|
||||
data._boundHandle = null;
|
||||
data._completed = false;
|
||||
|
||||
if (data._preAllocated != null)
|
||||
data._preAllocated.Release();
|
||||
else
|
||||
Win32ThreadPoolNativeOverlapped.Free(threadPoolOverlapped);
|
||||
}
|
||||
|
||||
[CLSCompliant(false)]
|
||||
public static unsafe object GetNativeOverlappedState(NativeOverlapped* overlapped)
|
||||
{
|
||||
if (overlapped == null)
|
||||
throw new ArgumentNullException(nameof(overlapped));
|
||||
|
||||
Win32ThreadPoolNativeOverlapped* threadPoolOverlapped = Win32ThreadPoolNativeOverlapped.FromNativeOverlapped(overlapped);
|
||||
Win32ThreadPoolNativeOverlapped.OverlappedData data = GetOverlappedData(threadPoolOverlapped, null);
|
||||
|
||||
return threadPoolOverlapped->Data._state;
|
||||
}
|
||||
|
||||
private static unsafe Win32ThreadPoolNativeOverlapped.OverlappedData GetOverlappedData(Win32ThreadPoolNativeOverlapped* overlapped, ThreadPoolBoundHandle expectedBoundHandle)
|
||||
{
|
||||
Win32ThreadPoolNativeOverlapped.OverlappedData data = overlapped->Data;
|
||||
|
||||
if (data._boundHandle == null)
|
||||
throw new ArgumentException(SR.Argument_NativeOverlappedAlreadyFree, nameof(overlapped));
|
||||
|
||||
if (expectedBoundHandle != null && data._boundHandle != expectedBoundHandle)
|
||||
throw new ArgumentException(SR.Argument_NativeOverlappedWrongBoundHandle, nameof(overlapped));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
private static unsafe void OnNativeIOCompleted(IntPtr instance, IntPtr context, IntPtr overlappedPtr, uint ioResult, UIntPtr numberOfBytesTransferred, IntPtr ioPtr)
|
||||
{
|
||||
Win32ThreadPoolNativeOverlapped* overlapped = (Win32ThreadPoolNativeOverlapped*)overlappedPtr;
|
||||
|
||||
ThreadPoolBoundHandle boundHandle = overlapped->Data._boundHandle;
|
||||
if (boundHandle == null)
|
||||
throw new InvalidOperationException(SR.Argument_NativeOverlappedAlreadyFree);
|
||||
|
||||
boundHandle.Release();
|
||||
|
||||
Win32ThreadPoolNativeOverlapped.CompleteWithCallback(ioResult, (uint)numberOfBytesTransferred, overlapped);
|
||||
}
|
||||
|
||||
private bool AddRef()
|
||||
{
|
||||
return _lifetime.AddRef(this);
|
||||
}
|
||||
|
||||
private void Release()
|
||||
{
|
||||
_lifetime.Release(this);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_lifetime.Dispose(this);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
~ThreadPoolBoundHandle()
|
||||
{
|
||||
//
|
||||
// During shutdown, don't automatically clean up, because this instance may still be
|
||||
// reachable/usable by other code.
|
||||
//
|
||||
if (!Environment.HasShutdownStarted)
|
||||
Dispose();
|
||||
}
|
||||
|
||||
void IDeferredDisposable.OnFinalRelease(bool disposed)
|
||||
{
|
||||
if (disposed)
|
||||
_threadPoolHandle.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace System.Threading
|
||||
{
|
||||
partial struct Win32ThreadPoolNativeOverlapped
|
||||
{
|
||||
private unsafe class ExecutionContextCallbackArgs
|
||||
{
|
||||
internal uint _errorCode;
|
||||
internal uint _bytesWritten;
|
||||
internal Win32ThreadPoolNativeOverlapped* _overlapped;
|
||||
internal OverlappedData _data;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace System.Threading
|
||||
{
|
||||
partial struct Win32ThreadPoolNativeOverlapped
|
||||
{
|
||||
internal class OverlappedData
|
||||
{
|
||||
internal GCHandle[] _pinnedData;
|
||||
internal IOCompletionCallback _callback;
|
||||
internal object _state;
|
||||
internal ExecutionContext _executionContext;
|
||||
internal ThreadPoolBoundHandle _boundHandle;
|
||||
internal PreAllocatedOverlapped _preAllocated;
|
||||
internal bool _completed;
|
||||
|
||||
internal void Reset()
|
||||
{
|
||||
Debug.Assert(_boundHandle == null); //not in use
|
||||
|
||||
if (_pinnedData != null)
|
||||
{
|
||||
for (int i = 0; i < _pinnedData.Length; i++)
|
||||
{
|
||||
if (_pinnedData[i].IsAllocated && _pinnedData[i].Target != null)
|
||||
_pinnedData[i].Target = null;
|
||||
}
|
||||
}
|
||||
|
||||
_callback = null;
|
||||
_state = null;
|
||||
_executionContext = null;
|
||||
_completed = false;
|
||||
_preAllocated = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace System.Threading
|
||||
{
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal partial struct Win32ThreadPoolNativeOverlapped
|
||||
{
|
||||
// Per-thread cache of the args object, so we don't have to allocate a new one each time.
|
||||
[ThreadStatic]
|
||||
private static ExecutionContextCallbackArgs t_executionContextCallbackArgs;
|
||||
|
||||
private static ContextCallback s_executionContextCallback;
|
||||
private static OverlappedData[] s_dataArray;
|
||||
private static int s_dataCount; // Current number of valid entries in _dataArray
|
||||
private static IntPtr s_freeList; // Lock-free linked stack of free ThreadPoolNativeOverlapped instances.
|
||||
|
||||
private NativeOverlapped _overlapped; // must be first, so we can cast to and from NativeOverlapped.
|
||||
private IntPtr _nextFree; // if this instance if free, points to the next free instance.
|
||||
private int _dataIndex; // Index in _dataArray of this instance's OverlappedData.
|
||||
|
||||
internal OverlappedData Data
|
||||
{
|
||||
get { return s_dataArray[_dataIndex]; }
|
||||
}
|
||||
|
||||
internal static unsafe Win32ThreadPoolNativeOverlapped* Allocate(IOCompletionCallback callback, object state, object pinData, PreAllocatedOverlapped preAllocated)
|
||||
{
|
||||
Win32ThreadPoolNativeOverlapped* overlapped = AllocateNew();
|
||||
try
|
||||
{
|
||||
overlapped->SetData(callback, state, pinData, preAllocated);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Free(overlapped);
|
||||
throw;
|
||||
}
|
||||
return overlapped;
|
||||
}
|
||||
|
||||
private static unsafe Win32ThreadPoolNativeOverlapped* AllocateNew()
|
||||
{
|
||||
IntPtr freePtr;
|
||||
Win32ThreadPoolNativeOverlapped* overlapped;
|
||||
OverlappedData data;
|
||||
|
||||
// Find a free Overlapped
|
||||
while ((freePtr = Volatile.Read(ref s_freeList)) != IntPtr.Zero)
|
||||
{
|
||||
overlapped = (Win32ThreadPoolNativeOverlapped*)freePtr;
|
||||
|
||||
if (Interlocked.CompareExchange(ref s_freeList, overlapped->_nextFree, freePtr) != freePtr)
|
||||
continue;
|
||||
|
||||
overlapped->_nextFree = IntPtr.Zero;
|
||||
return overlapped;
|
||||
}
|
||||
|
||||
// None are free; allocate a new one.
|
||||
overlapped = (Win32ThreadPoolNativeOverlapped*)Marshal.AllocHGlobal(sizeof(Win32ThreadPoolNativeOverlapped));
|
||||
*overlapped = default(Win32ThreadPoolNativeOverlapped);
|
||||
|
||||
// Allocate a OverlappedData object, and an index at which to store it in _dataArray.
|
||||
data = new OverlappedData();
|
||||
int dataIndex = Interlocked.Increment(ref s_dataCount) - 1;
|
||||
|
||||
// Make sure we didn't wrap around.
|
||||
if (dataIndex < 0)
|
||||
Environment.FailFast("Too many outstanding Win32ThreadPoolNativeOverlapped instances");
|
||||
|
||||
while (true)
|
||||
{
|
||||
OverlappedData[] dataArray = Volatile.Read(ref s_dataArray);
|
||||
int currentLength = dataArray == null ? 0 : dataArray.Length;
|
||||
|
||||
// If the current array is too small, create a new, larger one.
|
||||
if (currentLength <= dataIndex)
|
||||
{
|
||||
int newLength = currentLength;
|
||||
if (newLength == 0)
|
||||
newLength = 128;
|
||||
while (newLength <= dataIndex)
|
||||
newLength = (newLength * 3) / 2;
|
||||
|
||||
OverlappedData[] newDataArray = dataArray;
|
||||
Array.Resize(ref newDataArray, newLength);
|
||||
|
||||
if (Interlocked.CompareExchange(ref s_dataArray, newDataArray, dataArray) != dataArray)
|
||||
continue; // Someone else got the free one, try again
|
||||
|
||||
dataArray = newDataArray;
|
||||
}
|
||||
|
||||
// If we haven't stored this object in the array yet, do so now. Then we need to make another pass through
|
||||
// the loop, in case another thread resized the array before we made this update.
|
||||
if (s_dataArray[dataIndex] == null)
|
||||
{
|
||||
// Full fence so this write can't move past subsequent reads.
|
||||
Interlocked.Exchange(ref dataArray[dataIndex], data);
|
||||
continue;
|
||||
}
|
||||
|
||||
// We're already in the array, so we're done.
|
||||
Debug.Assert(dataArray[dataIndex] == data);
|
||||
overlapped->_dataIndex = dataIndex;
|
||||
return overlapped;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetData(IOCompletionCallback callback, object state, object pinData, PreAllocatedOverlapped preAllocated)
|
||||
{
|
||||
Debug.Assert(callback != null);
|
||||
|
||||
OverlappedData data = Data;
|
||||
|
||||
data._callback = callback;
|
||||
data._state = state;
|
||||
data._executionContext = ExecutionContext.Capture();
|
||||
data._preAllocated = preAllocated;
|
||||
|
||||
//
|
||||
// pinData can be any blittable type to be pinned, *or* an instance of object[] each element of which refers to
|
||||
// an instance of a blittable type to be pinned.
|
||||
//
|
||||
if (pinData != null)
|
||||
{
|
||||
object[] objArray = pinData as object[];
|
||||
if (objArray != null && objArray.GetType() == typeof(object[]))
|
||||
{
|
||||
if (data._pinnedData == null || data._pinnedData.Length < objArray.Length)
|
||||
Array.Resize(ref data._pinnedData, objArray.Length);
|
||||
|
||||
for (int i = 0; i < objArray.Length; i++)
|
||||
{
|
||||
if (!data._pinnedData[i].IsAllocated)
|
||||
data._pinnedData[i] = GCHandle.Alloc(objArray[i], GCHandleType.Pinned);
|
||||
else
|
||||
data._pinnedData[i].Target = objArray[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (data._pinnedData == null)
|
||||
data._pinnedData = new GCHandle[1];
|
||||
|
||||
if (!data._pinnedData[0].IsAllocated)
|
||||
data._pinnedData[0] = GCHandle.Alloc(pinData, GCHandleType.Pinned);
|
||||
else
|
||||
data._pinnedData[0].Target = pinData;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static unsafe void Free(Win32ThreadPoolNativeOverlapped* overlapped)
|
||||
{
|
||||
// Reset all data.
|
||||
overlapped->Data.Reset();
|
||||
overlapped->_overlapped = default(NativeOverlapped);
|
||||
|
||||
// Add to the free list.
|
||||
while (true)
|
||||
{
|
||||
IntPtr freePtr = Volatile.Read(ref s_freeList);
|
||||
overlapped->_nextFree = freePtr;
|
||||
|
||||
if (Interlocked.CompareExchange(ref s_freeList, (IntPtr)overlapped, freePtr) == freePtr)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
internal static unsafe NativeOverlapped* ToNativeOverlapped(Win32ThreadPoolNativeOverlapped* overlapped)
|
||||
{
|
||||
return (NativeOverlapped*)overlapped;
|
||||
}
|
||||
|
||||
internal static unsafe Win32ThreadPoolNativeOverlapped* FromNativeOverlapped(NativeOverlapped* overlapped)
|
||||
{
|
||||
return (Win32ThreadPoolNativeOverlapped*)overlapped;
|
||||
}
|
||||
|
||||
internal static unsafe void CompleteWithCallback(uint errorCode, uint bytesWritten, Win32ThreadPoolNativeOverlapped* overlapped)
|
||||
{
|
||||
OverlappedData data = overlapped->Data;
|
||||
|
||||
Debug.Assert(!data._completed);
|
||||
data._completed = true;
|
||||
|
||||
ContextCallback callback = s_executionContextCallback;
|
||||
if (callback == null)
|
||||
s_executionContextCallback = callback = OnExecutionContextCallback;
|
||||
|
||||
// Get an args object from the per-thread cache.
|
||||
ExecutionContextCallbackArgs args = t_executionContextCallbackArgs;
|
||||
if (args == null)
|
||||
args = new ExecutionContextCallbackArgs();
|
||||
|
||||
t_executionContextCallbackArgs = null;
|
||||
|
||||
args._errorCode = errorCode;
|
||||
args._bytesWritten = bytesWritten;
|
||||
args._overlapped = overlapped;
|
||||
args._data = data;
|
||||
|
||||
ExecutionContext.Run(data._executionContext, callback, args);
|
||||
}
|
||||
|
||||
private static unsafe void OnExecutionContextCallback(object state)
|
||||
{
|
||||
ExecutionContextCallbackArgs args = (ExecutionContextCallbackArgs)state;
|
||||
|
||||
uint errorCode = args._errorCode;
|
||||
uint bytesWritten = args._bytesWritten;
|
||||
Win32ThreadPoolNativeOverlapped* overlapped = args._overlapped;
|
||||
OverlappedData data = args._data;
|
||||
|
||||
// Put the args object back in the per-thread cache, now that we're done with it.
|
||||
args._data = null;
|
||||
t_executionContextCallbackArgs = args;
|
||||
|
||||
data._callback(errorCode, bytesWritten, ToNativeOverlapped(overlapped));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace System.Threading
|
||||
{
|
||||
public sealed class PreAllocatedOverlapped : IDisposable, IDeferredDisposable
|
||||
{
|
||||
internal unsafe readonly Win32ThreadPoolNativeOverlapped* _overlapped;
|
||||
private DeferredDisposableLifetime<PreAllocatedOverlapped> _lifetime;
|
||||
|
||||
[CLSCompliant(false)]
|
||||
public unsafe PreAllocatedOverlapped(IOCompletionCallback callback, object state, object pinData)
|
||||
{
|
||||
if (callback == null)
|
||||
throw new ArgumentNullException(nameof(callback));
|
||||
|
||||
_overlapped = Win32ThreadPoolNativeOverlapped.Allocate(callback, state, pinData, this);
|
||||
}
|
||||
|
||||
internal bool AddRef()
|
||||
{
|
||||
return _lifetime.AddRef(this);
|
||||
}
|
||||
|
||||
internal void Release()
|
||||
{
|
||||
_lifetime.Release(this);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_lifetime.Dispose(this);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
~PreAllocatedOverlapped()
|
||||
{
|
||||
//
|
||||
// During shutdown, don't automatically clean up, because this instance may still be
|
||||
// reachable/usable by other code.
|
||||
//
|
||||
if (!Environment.HasShutdownStarted)
|
||||
Dispose();
|
||||
}
|
||||
|
||||
unsafe void IDeferredDisposable.OnFinalRelease(bool disposed)
|
||||
{
|
||||
if (_overlapped != null)
|
||||
{
|
||||
if (disposed)
|
||||
Win32ThreadPoolNativeOverlapped.Free(_overlapped);
|
||||
else
|
||||
*Win32ThreadPoolNativeOverlapped.ToNativeOverlapped(_overlapped) = default(NativeOverlapped);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
29
external/corefx/src/System.Threading.Overlapped/tests/AsyncResult.cs
vendored
Normal file
29
external/corefx/src/System.Threading.Overlapped/tests/AsyncResult.cs
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
public class AsyncResult : IAsyncResult
|
||||
{
|
||||
public object AsyncState
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
public System.Threading.WaitHandle AsyncWaitHandle
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
public bool CompletedSynchronously
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
public bool IsCompleted
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user