Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 0ec3434

Browse files
author
Matt Cohn
committed
Address PR feedback - build this library only for Windows, test fixes
Build this library only for Windows Remove ResInputPath msbuild property and use the same default value Properly dispose resources in tests. Add test coverage: FreeNativeOverlapped_WithWrongHandle_ThrowsArgumentException AllocateNativeOverlapped_PreAllocated_WhenAlreadyAllocated_Throws... ArgumentException Fix ThreadPoolBoundHandle_GetNativeOverlappedStateTests when file write completes synchronously. Pin buffers during asynchronous file write
1 parent d235ddf commit 0ec3434

10 files changed

+313
-193
lines changed

src/System.Threading.Overlapped/src/System.Threading.Overlapped.CoreCLR.csproj

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,12 @@
99
<OutputType>Library</OutputType>
1010
<ProjectGuid>{6A07CCB8-3E59-47e7-B3DD-DB1F6FC501D5}</ProjectGuid>
1111
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
12-
<ResInputPath>$(MSBuildThisFileDirectory)Resources</ResInputPath>
1312
<IsPartialFacadeAssembly>true</IsPartialFacadeAssembly>
1413
<NuGetTargetFrameworkMoniker>DNXCore,Version=v5.0</NuGetTargetFrameworkMoniker>
1514
</PropertyGroup>
1615
<!-- Help VS understand available configurations -->
1716
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Windows_Debug|AnyCPU' " />
1817
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Windows_Release|AnyCPU' " />
19-
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Linux_Debug|AnyCPU' " />
20-
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Linux_Release|AnyCPU' " />
21-
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'OSX_Debug|AnyCPU' " />
22-
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'OSX_Release|AnyCPU' " />
2318
<ItemGroup>
2419
<ProjectReference Include="..\..\System.Diagnostics.Debug\src\System.Diagnostics.Debug.csproj">
2520
<Project>{E7E8DE8A-9EC1-46A8-A6EE-727DB32DBEB8}</Project>

src/System.Threading.Overlapped/tests/System.Threading.Overlapped.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
<AssemblyName>System.Threading.Overlapped.Tests</AssemblyName>
99
<ProjectGuid>{861A3318-35AD-46ac-8257-8D5D2479BAD9}</ProjectGuid>
1010
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
11+
<UnsupportedPlatforms>Linux;OSX</UnsupportedPlatforms>
1112
</PropertyGroup>
1213
<!-- Default configurations to help VS understand the configurations -->
1314
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' " />

src/System.Threading.Overlapped/tests/ThreadPoolBoundHandle_AllocateNativeOverlappedTests.cs

Lines changed: 148 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -11,66 +11,86 @@ public partial class ThreadPoolBoundHandleTests
1111
[Fact]
1212
public unsafe void AllocateNativeOverlapped_NullAsCallback_ThrowsArgumentNullException()
1313
{
14-
ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle();
15-
16-
Assert.Throws<ArgumentNullException>("callback", () =>
14+
using(ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle())
1715
{
18-
handle.AllocateNativeOverlapped(null, new object(), new byte[256]);
19-
});
16+
Assert.Throws<ArgumentNullException>("callback", () =>
17+
{
18+
handle.AllocateNativeOverlapped(null, new object(), new byte[256]);
19+
});
20+
}
2021
}
2122

2223
[Fact]
2324
public unsafe void AllocateNativeOverlapped_PreAllocated_ThrowsArgumentNullException()
2425
{
25-
ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle();
26-
27-
Assert.Throws<ArgumentNullException>("preAllocated", () =>
26+
using(ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle())
2827
{
29-
handle.AllocateNativeOverlapped((PreAllocatedOverlapped)null);
30-
});
28+
Assert.Throws<ArgumentNullException>("preAllocated", () =>
29+
{
30+
handle.AllocateNativeOverlapped((PreAllocatedOverlapped)null);
31+
});
32+
}
3133
}
3234

3335
[Fact]
3436
public unsafe void AllocateNativeOverlapped_NullAsContext_DoesNotThrow()
3537
{
36-
ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle();
37-
NativeOverlapped* result = handle.AllocateNativeOverlapped((_, __, ___) => { }, (object)null, new byte[256]);
38+
using(ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle())
39+
{
40+
NativeOverlapped* result = handle.AllocateNativeOverlapped((_, __, ___) => { }, (object)null, new byte[256]);
41+
42+
Assert.True(result != null);
3843

39-
Assert.True(result != null);
44+
handle.FreeNativeOverlapped(result);
45+
}
4046
}
4147

4248
[Fact]
4349
public unsafe void AllocateNativeOverlapped_NullAsPinData_DoesNotThrow()
4450
{
45-
ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle();
46-
NativeOverlapped* result = handle.AllocateNativeOverlapped((_, __, ___) => { }, new object(), (byte[])null);
51+
using(ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle())
52+
{
53+
NativeOverlapped* result = handle.AllocateNativeOverlapped((_, __, ___) => { }, new object(), (byte[])null);
54+
55+
Assert.True(result != null);
4756

48-
Assert.True(result != null);
57+
handle.FreeNativeOverlapped(result);
58+
}
4959
}
5060

5161
[Fact]
5262
public unsafe void AllocateNativeOverlapped_EmptyArrayAsPinData_DoesNotThrow()
5363
{
54-
ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle();
55-
NativeOverlapped* result = handle.AllocateNativeOverlapped((_, __, ___) => { }, new object(), new byte[0]);
64+
using(ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle())
65+
{
66+
NativeOverlapped* result = handle.AllocateNativeOverlapped((_, __, ___) => { }, new object(), new byte[0]);
67+
68+
Assert.True(result != null);
5669

57-
Assert.True(result != null);
70+
handle.FreeNativeOverlapped(result);
71+
}
5872
}
5973

6074
[Fact]
6175
public unsafe void AllocateNativeOverlapped_NonBlittableTypeAsPinData_Throws()
6276
{
63-
ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle();
64-
Assert.Throws<ArgumentException>(() => handle.AllocateNativeOverlapped((_, __, ___) => { }, new object(), new NonBlittableType() { s = "foo" }));
77+
using(ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle())
78+
{
79+
Assert.Throws<ArgumentException>(() => handle.AllocateNativeOverlapped((_, __, ___) => { }, new object(), new NonBlittableType() { s = "foo" }));
80+
}
6581
}
6682

6783
[Fact]
6884
public unsafe void AllocateNativeOverlapped_BlittableTypeAsPinData_DoesNotThrow()
6985
{
70-
ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle();
71-
NativeOverlapped* result = handle.AllocateNativeOverlapped((_, __, ___) => { }, new object(), new BlittableType() { i = 42 });
86+
using(ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle())
87+
{
88+
NativeOverlapped* result = handle.AllocateNativeOverlapped((_, __, ___) => { }, new object(), new BlittableType() { i = 42 });
7289

73-
Assert.True(result != null);
90+
Assert.True(result != null);
91+
92+
handle.FreeNativeOverlapped(result);
93+
}
7494
}
7595

7696
[Fact]
@@ -81,10 +101,14 @@ public unsafe void AllocateNativeOverlapped_ObjectArrayAsPinData_DoesNotThrow()
81101
new BlittableType() { i = 1 },
82102
new byte[5],
83103
};
84-
ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle();
85-
NativeOverlapped* result = handle.AllocateNativeOverlapped((_, __, ___) => { }, new object(), array);
104+
using(ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle())
105+
{
106+
NativeOverlapped* result = handle.AllocateNativeOverlapped((_, __, ___) => { }, new object(), array);
86107

87-
Assert.True(result != null);
108+
Assert.True(result != null);
109+
110+
handle.FreeNativeOverlapped(result);
111+
}
88112
}
89113

90114
[Fact]
@@ -95,113 +119,153 @@ public unsafe void AllocateNativeOverlapped_ObjectArrayWithNonBlittableTypeAsPin
95119
new NonBlittableType() { s = "foo" },
96120
new byte[5],
97121
};
98-
ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle();
99-
Assert.Throws<ArgumentException>(() => handle.AllocateNativeOverlapped((_, __, ___) => { }, new object(), array));
122+
using(ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle())
123+
{
124+
Assert.Throws<ArgumentException>(() => handle.AllocateNativeOverlapped((_, __, ___) => { }, new object(), array));
125+
}
100126
}
101127

102128
[Fact]
103129
public unsafe void AllocateNativeOverlapped_ReturnedNativeOverlapped_AllFieldsZero()
104130
{
105-
ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle();
106-
NativeOverlapped* overlapped = handle.AllocateNativeOverlapped((_, __, ___) => { }, new object(), new byte[256]);
131+
using(ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle())
132+
{
133+
NativeOverlapped* overlapped = handle.AllocateNativeOverlapped((_, __, ___) => { }, new object(), new byte[256]);
107134

108-
Assert.Equal(IntPtr.Zero, overlapped->InternalLow);
109-
Assert.Equal(IntPtr.Zero, overlapped->InternalHigh);
110-
Assert.Equal(0, overlapped->OffsetLow);
111-
Assert.Equal(0, overlapped->OffsetHigh);
112-
Assert.Equal(IntPtr.Zero, overlapped->EventHandle);
135+
Assert.Equal(IntPtr.Zero, overlapped->InternalLow);
136+
Assert.Equal(IntPtr.Zero, overlapped->InternalHigh);
137+
Assert.Equal(0, overlapped->OffsetLow);
138+
Assert.Equal(0, overlapped->OffsetHigh);
139+
Assert.Equal(IntPtr.Zero, overlapped->EventHandle);
140+
141+
handle.FreeNativeOverlapped(overlapped);
142+
}
113143
}
114144

115145
[Fact]
116146
public unsafe void AllocateNativeOverlapped_PreAllocated_ReturnedNativeOverlapped_AllFieldsZero()
117147
{
118-
ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle();
119-
PreAllocatedOverlapped preAlloc = new PreAllocatedOverlapped((_, __, ___) => { }, new object(), new byte[256]);
120-
NativeOverlapped* overlapped = handle.AllocateNativeOverlapped(preAlloc);
121-
122-
Assert.Equal(IntPtr.Zero, overlapped->InternalLow);
123-
Assert.Equal(IntPtr.Zero, overlapped->InternalHigh);
124-
Assert.Equal(0, overlapped->OffsetLow);
125-
Assert.Equal(0, overlapped->OffsetHigh);
126-
Assert.Equal(IntPtr.Zero, overlapped->EventHandle);
148+
using(ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle())
149+
{
150+
using(PreAllocatedOverlapped preAlloc = new PreAllocatedOverlapped((_, __, ___) => { }, new object(), new byte[256]))
151+
{
152+
NativeOverlapped* overlapped = handle.AllocateNativeOverlapped(preAlloc);
153+
154+
Assert.Equal(IntPtr.Zero, overlapped->InternalLow);
155+
Assert.Equal(IntPtr.Zero, overlapped->InternalHigh);
156+
Assert.Equal(0, overlapped->OffsetLow);
157+
Assert.Equal(0, overlapped->OffsetHigh);
158+
Assert.Equal(IntPtr.Zero, overlapped->EventHandle);
159+
160+
handle.FreeNativeOverlapped(overlapped);
161+
}
162+
}
127163
}
128164

129165
[Fact]
130166
public unsafe void AllocateNativeOverlapped_PossibleReusedReturnedNativeOverlapped_OffsetLowAndOffsetHighSetToZero()
131167
{ // The CLR reuses NativeOverlapped underneath, check to make sure that they reset fields back to zero
132168

133-
ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle();
134-
NativeOverlapped* overlapped = handle.AllocateNativeOverlapped((_, __, ___) => { }, new object(), new byte[256]);
135-
overlapped->OffsetHigh = 1;
136-
overlapped->OffsetLow = 1;
137-
handle.FreeNativeOverlapped(overlapped);
169+
using(ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle())
170+
{
171+
NativeOverlapped* overlapped = handle.AllocateNativeOverlapped((_, __, ___) => { }, new object(), new byte[256]);
172+
overlapped->OffsetHigh = 1;
173+
overlapped->OffsetLow = 1;
174+
handle.FreeNativeOverlapped(overlapped);
175+
176+
overlapped = handle.AllocateNativeOverlapped((errorCode, numBytes, overlap) => { }, new object(), new byte[256]);
138177

139-
overlapped = handle.AllocateNativeOverlapped((errorCode, numBytes, overlap) => { }, new object(), new byte[256]);
178+
Assert.Equal(IntPtr.Zero, overlapped->InternalLow);
179+
Assert.Equal(IntPtr.Zero, overlapped->InternalHigh);
180+
Assert.Equal(0, overlapped->OffsetLow);
181+
Assert.Equal(0, overlapped->OffsetHigh);
182+
Assert.Equal(IntPtr.Zero, overlapped->EventHandle);
140183

141-
Assert.Equal(IntPtr.Zero, overlapped->InternalLow);
142-
Assert.Equal(IntPtr.Zero, overlapped->InternalHigh);
143-
Assert.Equal(0, overlapped->OffsetLow);
144-
Assert.Equal(0, overlapped->OffsetHigh);
145-
Assert.Equal(IntPtr.Zero, overlapped->EventHandle);
184+
handle.FreeNativeOverlapped(overlapped);
185+
}
146186
}
147187

148188
[Fact]
149189
public unsafe void AllocateNativeOverlapped_PreAllocated_ReusedReturnedNativeOverlapped_OffsetLowAndOffsetHighSetToZero()
150190
{ // The CLR reuses NativeOverlapped underneath, check to make sure that they reset fields back to zero
151191

152-
ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle();
153-
PreAllocatedOverlapped preAlloc = new PreAllocatedOverlapped((_, __, ___) => { }, new object(), new byte[256]);
154-
NativeOverlapped* overlapped = handle.AllocateNativeOverlapped(preAlloc);
155-
overlapped->OffsetHigh = 1;
156-
overlapped->OffsetLow = 1;
157-
handle.FreeNativeOverlapped(overlapped);
158-
159-
overlapped = handle.AllocateNativeOverlapped(preAlloc);
160-
161-
Assert.Equal(IntPtr.Zero, overlapped->InternalLow);
162-
Assert.Equal(IntPtr.Zero, overlapped->InternalHigh);
163-
Assert.Equal(0, overlapped->OffsetLow);
164-
Assert.Equal(0, overlapped->OffsetHigh);
165-
Assert.Equal(IntPtr.Zero, overlapped->EventHandle);
192+
using(ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle())
193+
{
194+
PreAllocatedOverlapped preAlloc = new PreAllocatedOverlapped((_, __, ___) => { }, new object(), new byte[256]);
195+
NativeOverlapped* overlapped = handle.AllocateNativeOverlapped(preAlloc);
196+
overlapped->OffsetHigh = 1;
197+
overlapped->OffsetLow = 1;
198+
handle.FreeNativeOverlapped(overlapped);
199+
200+
overlapped = handle.AllocateNativeOverlapped(preAlloc);
201+
202+
Assert.Equal(IntPtr.Zero, overlapped->InternalLow);
203+
Assert.Equal(IntPtr.Zero, overlapped->InternalHigh);
204+
Assert.Equal(0, overlapped->OffsetLow);
205+
Assert.Equal(0, overlapped->OffsetHigh);
206+
Assert.Equal(IntPtr.Zero, overlapped->EventHandle);
207+
208+
handle.FreeNativeOverlapped(overlapped);
209+
}
166210
}
167211

168212
[Fact]
169213
public unsafe void AllocateNativeOverlapped_WhenDisposed_ThrowsObjectDisposedException()
170214
{
171-
ThreadPoolBoundHandle boundHandle = CreateThreadPoolBoundHandle();
172-
boundHandle.Dispose();
215+
ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle();
216+
handle.Dispose();
173217

174218
Assert.Throws<ObjectDisposedException>(() =>
175219
{
176-
boundHandle.AllocateNativeOverlapped((_, __, ___) => { }, new object(), new byte[256]);
220+
handle.AllocateNativeOverlapped((_, __, ___) => { }, new object(), new byte[256]);
177221
});
178222
}
179223

180224
[Fact]
181225
public unsafe void AllocateNativeOverlapped_PreAllocated_WhenDisposed_ThrowsObjectDisposedException()
182226
{
183-
ThreadPoolBoundHandle boundHandle = CreateThreadPoolBoundHandle();
184-
185-
PreAllocatedOverlapped preAlloc = new PreAllocatedOverlapped(delegate { }, null, null);
186-
preAlloc.Dispose();
187-
188-
Assert.Throws<ObjectDisposedException>(() =>
227+
using(ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle())
189228
{
190-
boundHandle.AllocateNativeOverlapped(preAlloc);
191-
});
229+
PreAllocatedOverlapped preAlloc = new PreAllocatedOverlapped(delegate { }, null, null);
230+
preAlloc.Dispose();
231+
232+
Assert.Throws<ObjectDisposedException>(() =>
233+
{
234+
handle.AllocateNativeOverlapped(preAlloc);
235+
});
236+
}
192237
}
193238

194239
[Fact]
195240
public unsafe void AllocateNativeOverlapped_PreAllocated_WhenHandleDisposed_ThrowsObjectDisposedException()
196241
{
197-
ThreadPoolBoundHandle boundHandle = CreateThreadPoolBoundHandle();
198-
boundHandle.Dispose();
242+
ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle();
243+
handle.Dispose();
199244

200245
PreAllocatedOverlapped preAlloc = new PreAllocatedOverlapped(delegate { }, null, null);
201246

202247
Assert.Throws<ObjectDisposedException>(() =>
203248
{
204-
boundHandle.AllocateNativeOverlapped(preAlloc);
249+
handle.AllocateNativeOverlapped(preAlloc);
205250
});
206251
}
252+
253+
[Fact]
254+
public unsafe void AllocateNativeOverlapped_PreAllocated_WhenAlreadyAllocated_ThrowsArgumentException()
255+
{
256+
using(ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle())
257+
{
258+
using(PreAllocatedOverlapped preAlloc = new PreAllocatedOverlapped(delegate { }, null, null))
259+
{
260+
NativeOverlapped* overlapped = handle.AllocateNativeOverlapped(preAlloc);
261+
262+
Assert.Throws<ArgumentException>(() =>
263+
{
264+
handle.AllocateNativeOverlapped(preAlloc);
265+
});
266+
267+
handle.FreeNativeOverlapped(overlapped);
268+
}
269+
}
270+
}
207271
}

0 commit comments

Comments
 (0)