[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"
         }));
     }
 }
Example #7
0
    [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);
        }
    }