Imported Upstream version 5.0.0.42

Former-commit-id: fd56571888259555122d8a0f58c68838229cea2b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2017-04-10 11:41:01 +00:00
parent 1190d13a04
commit 6bdd276d05
19939 changed files with 3099680 additions and 93811 deletions

View 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

View 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>

View 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>

View 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; }
}
}

View 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>

View 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>

View 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>

View 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>

View 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());
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}
}
}

View 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;
}
}
}
}
}

View 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);
}

View 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;
}
}

View 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();
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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));
}
}
}

View File

@@ -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);
}
}
}
}

View 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