[PlatformSpecific(TestPlatforms.Windows)] // ThreadPoolBoundHandle.BindHandle is not supported on Unix public unsafe void AllocateNativeOverlapped_PossibleReusedReturnedNativeOverlapped_OffsetLowAndOffsetHighSetToZero(bool useUnsafe) { // The CLR reuses NativeOverlapped underneath, check to make sure that they reset fields back to zero using (ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle()) { NativeOverlapped *overlapped = useUnsafe ? handle.UnsafeAllocateNativeOverlapped((_, __, ___) => { }, new object(), new byte[256]) : handle.AllocateNativeOverlapped((_, __, ___) => { }, new object(), new byte[256]); overlapped->OffsetHigh = 1; overlapped->OffsetLow = 1; handle.FreeNativeOverlapped(overlapped); overlapped = useUnsafe ? handle.UnsafeAllocateNativeOverlapped((errorCode, numBytes, overlap) => { }, new object(), new byte[256]) : handle.AllocateNativeOverlapped((errorCode, numBytes, overlap) => { }, new object(), new byte[256]); Assert.Equal(IntPtr.Zero, overlapped->InternalLow); Assert.Equal(IntPtr.Zero, overlapped->InternalHigh); Assert.Equal(0, overlapped->OffsetLow); Assert.Equal(0, overlapped->OffsetHigh); Assert.Equal(IntPtr.Zero, overlapped->EventHandle); handle.FreeNativeOverlapped(overlapped); } }
[PlatformSpecific(TestPlatforms.Windows)] // ThreadPoolBoundHandle.BindHandle is not supported on Unix public unsafe void AllocateNativeOverlapped_NullAsCallback_ThrowsArgumentNullException() { using (ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle()) { AssertExtensions.Throws <ArgumentNullException>("callback", () => handle.AllocateNativeOverlapped(null, new object(), new byte[256])); AssertExtensions.Throws <ArgumentNullException>("callback", () => handle.UnsafeAllocateNativeOverlapped(null, new object(), new byte[256])); } }
[PlatformSpecific(TestPlatforms.Windows)] // ThreadPoolBoundHandle.BindHandle is not supported on Unix public unsafe void AllocateNativeOverlapped_WhenDisposed_ThrowsObjectDisposedException() { ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle(); handle.Dispose(); Assert.Throws <ObjectDisposedException>(() => handle.AllocateNativeOverlapped((_, __, ___) => { }, new object(), new byte[256])); Assert.Throws <ObjectDisposedException>(() => handle.UnsafeAllocateNativeOverlapped((_, __, ___) => { }, new object(), new byte[256])); }
[PlatformSpecific(TestPlatforms.Windows)] // ThreadPoolBoundHandle.BindHandle is not supported on Unix public unsafe void AllocateNativeOverlapped_EmptyArrayAsPinData_DoesNotThrow() { using (ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle()) { NativeOverlapped *result = handle.AllocateNativeOverlapped((_, __, ___) => { }, new object(), new byte[0]); Assert.True(result != null); handle.FreeNativeOverlapped(result); result = handle.UnsafeAllocateNativeOverlapped((_, __, ___) => { }, new object(), new byte[0]); Assert.True(result != null); handle.FreeNativeOverlapped(result); } }
[PlatformSpecific(TestPlatforms.Windows)] // ThreadPoolBoundHandle.BindHandle is not supported on Unix public unsafe void AllocateNativeOverlapped_NullAsContext_DoesNotThrow() { using (ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle()) { NativeOverlapped *result = handle.AllocateNativeOverlapped((_, __, ___) => { }, (object)null, new byte[256]); Assert.True(result != null); handle.FreeNativeOverlapped(result); result = handle.UnsafeAllocateNativeOverlapped((_, __, ___) => { }, (object)null, new byte[256]); Assert.True(result != null); handle.FreeNativeOverlapped(result); } }
[PlatformSpecific(TestPlatforms.Windows)] // ThreadPoolBoundHandle.BindHandle is not supported on Unix public unsafe void AllocateNativeOverlapped_NonBlittableTypeAsPinData_Throws() { using (ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle()) { Assert.Throws <ArgumentException>(() => handle.AllocateNativeOverlapped((_, __, ___) => { }, new object(), new NonBlittableType() { s = "foo" })); Assert.Throws <ArgumentException>(() => handle.UnsafeAllocateNativeOverlapped((_, __, ___) => { }, new object(), new NonBlittableType() { s = "foo" })); } }
[PlatformSpecific(TestPlatforms.Windows)] // ThreadPoolBoundHandle.BindHandle is not supported on Unix public unsafe void FlowsAsyncLocalsToCallback(bool shouldFlow) { // Makes sure that we flow async locals to callback const int DATA_SIZE = 2; SafeHandle handle = HandleFactory.CreateAsyncFileHandleForWrite(Path.Combine(TestDirectory, @"AsyncLocal.tmp")); ThreadPoolBoundHandle boundHandle = ThreadPoolBoundHandle.BindHandle(handle); OverlappedContext context = new OverlappedContext(); byte[] data = new byte[DATA_SIZE]; AsyncLocal <int> asyncLocal = new AsyncLocal <int>(); asyncLocal.Value = 10; int?result = null; IOCompletionCallback callback = (_, __, ___) => { result = asyncLocal.Value; OnOverlappedOperationCompleted(_, __, ___); }; NativeOverlapped *overlapped = shouldFlow ? boundHandle.AllocateNativeOverlapped(callback, context, data) : boundHandle.UnsafeAllocateNativeOverlapped(callback, context, data); fixed(byte *p = data) { int retval = DllImport.WriteFile(boundHandle.Handle, p, DATA_SIZE, IntPtr.Zero, overlapped); if (retval == 0) { Assert.Equal(DllImport.ERROR_IO_PENDING, Marshal.GetLastPInvokeError()); } // Wait for overlapped operation to complete context.Event.WaitOne(); } boundHandle.FreeNativeOverlapped(overlapped); boundHandle.Dispose(); handle.Dispose(); Assert.Equal( shouldFlow ? 10 : 0, result); }
[PlatformSpecific(TestPlatforms.Windows)] // ThreadPoolBoundHandle.BindHandle is not supported on Unix public unsafe void AllocateNativeOverlapped_ReturnedNativeOverlapped_AllFieldsZero(bool useUnsafe) { using (ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle()) { NativeOverlapped *overlapped = useUnsafe ? handle.UnsafeAllocateNativeOverlapped((_, __, ___) => { }, new object(), new byte[256]) : handle.AllocateNativeOverlapped((_, __, ___) => { }, new object(), new byte[256]); Assert.Equal(IntPtr.Zero, overlapped->InternalLow); Assert.Equal(IntPtr.Zero, overlapped->InternalHigh); Assert.Equal(0, overlapped->OffsetLow); Assert.Equal(0, overlapped->OffsetHigh); Assert.Equal(IntPtr.Zero, overlapped->EventHandle); handle.FreeNativeOverlapped(overlapped); } }
[PlatformSpecific(TestPlatforms.Windows)] // ThreadPoolBoundHandle.BindHandle is not supported on Unix public unsafe void AllocateNativeOverlapped_ObjectArrayWithNonBlittableTypeAsPinData_Throws() { var array = new object[] { new NonBlittableType() { s = "foo" }, new byte[5], }; using (ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle()) { Assert.Throws <ArgumentException>(() => handle.AllocateNativeOverlapped((_, __, ___) => { }, new object(), array)); Assert.Throws <ArgumentException>(() => handle.UnsafeAllocateNativeOverlapped((_, __, ___) => { }, new object(), array)); } }
[PlatformSpecific(TestPlatforms.Windows)] // ThreadPoolBoundHandle.BindHandle is not supported on Unix public unsafe void AllocateNativeOverlapped_ObjectArrayAsPinData_DoesNotThrow() { var array = new object[] { new BlittableType() { i = 1 }, new byte[5], }; using (ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle()) { NativeOverlapped *result = handle.AllocateNativeOverlapped((_, __, ___) => { }, new object(), array); Assert.True(result != null); handle.FreeNativeOverlapped(result); result = handle.UnsafeAllocateNativeOverlapped((_, __, ___) => { }, new object(), array); Assert.True(result != null); handle.FreeNativeOverlapped(result); } }