[PlatformSpecific(TestPlatforms.Windows)] // ThreadPoolBoundHandle.BindHandle is not supported on Unix
    public unsafe void AllocateNativeOverlapped_PreAllocated_WhenAlreadyAllocated_ThrowsArgumentException(bool useUnsafe)
    {
        using (ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle())
        {
            using PreAllocatedOverlapped preAlloc = useUnsafe ?
                                                    PreAllocatedOverlapped.UnsafeCreate(delegate { }, null, null) :
                                                    new PreAllocatedOverlapped(delegate { }, null, null);

            NativeOverlapped *overlapped = handle.AllocateNativeOverlapped(preAlloc);

            AssertExtensions.Throws <ArgumentException>("preAllocated", () => handle.AllocateNativeOverlapped(preAlloc));

            handle.FreeNativeOverlapped(overlapped);
        }
    }
示例#2
0
 public unsafe void AllocateNativeOverlapped_ObjectArrayWithNonBlittableTypeAsPinData_Throws()
 {
     object[] array = new object[]
     {
         new NonBlittableType()
         {
             s = "foo"
         },
         new byte[5],
     };
     using (ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle())
     {
         Assert.Throws <ArgumentException>(() => handle.AllocateNativeOverlapped((_, __, ___) => { }, new object(), array));
     }
 }
    [PlatformSpecific(TestPlatforms.Windows)] // ThreadPoolBoundHandle.BindHandle is not supported on Unix
    public unsafe void AllocateNativeOverlapped_ReturnedNativeOverlapped_AllFieldsZero()
    {
        using (ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle())
        {
            NativeOverlapped *overlapped = 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);
        }
    }
示例#4
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);
    }
            // When doing IO asynchronously (i.e. _isAsync==true), this callback is
            // called by a free thread in the threadpool when the IO operation
            // completes.
            internal static void IOCallback(uint errorCode, uint numBytes, NativeOverlapped *pOverlapped)
            {
                // Extract the completion source from the overlapped.  The state in the overlapped
                // will either be a FileStreamStrategy (in the case where the preallocated overlapped was used),
                // in which case the operation being completed is its _currentOverlappedOwner, or it'll
                // be directly the FileStreamCompletionSource that's completing (in the case where the preallocated
                // overlapped was already in use by another operation).
                object?state = ThreadPoolBoundHandle.GetNativeOverlappedState(pOverlapped);

                Debug.Assert(state is Net5CompatFileStreamStrategy || state is CompletionSource);
                CompletionSource completionSource = state switch
                {
                    Net5CompatFileStreamStrategy strategy => strategy._currentOverlappedOwner !, // must be owned
                                 _ => (CompletionSource)state
                };

                Debug.Assert(completionSource != null);
                Debug.Assert(completionSource._overlapped == pOverlapped, "Overlaps don't match");

                // Handle reading from & writing to closed pipes.  While I'm not sure
                // this is entirely necessary anymore, maybe it's possible for
                // an async read on a pipe to be issued and then the pipe is closed,
                // returning this error.  This may very well be necessary.
                ulong packedResult;

                if (errorCode != 0 && errorCode != Interop.Errors.ERROR_BROKEN_PIPE && errorCode != Interop.Errors.ERROR_NO_DATA)
                {
                    packedResult = ((ulong)TaskSourceCodes.ResultError | errorCode);
                }
                else
                {
                    packedResult = ((ulong)TaskSourceCodes.ResultSuccess | numBytes);
                }

                // Stow the result so that other threads can observe it
                // And, if no other thread is registering cancellation, continue
                if (TaskSourceCodes.NoResult == Interlocked.Exchange(ref completionSource._result, (long)packedResult))
                {
                    // Successfully set the state, attempt to take back the callback
                    if (Interlocked.Exchange(ref completionSource._result, TaskSourceCodes.CompletedCallback) != TaskSourceCodes.NoResult)
                    {
                        // Successfully got the callback, finish the callback
                        completionSource.CompleteCallback(packedResult);
                    }
                    // else: Some other thread stole the result, so now it is responsible to finish the callback
                }
                // else: Some other thread is registering a cancellation, so it *must* finish the callback
            }
    [PlatformSpecific(TestPlatforms.Windows)] // ThreadPoolBoundHandle.BindHandle is not supported on Unix
    public unsafe void GetNativeOverlappedState_WhenUnderlyingStateIsNull_ReturnsNull()
    {
        using (SafeHandle handle = HandleFactory.CreateAsyncFileHandleForWrite(GetTestFilePath()))
        {
            using (ThreadPoolBoundHandle boundHandle = ThreadPoolBoundHandle.BindHandle(handle))
            {
                NativeOverlapped *overlapped = boundHandle.AllocateNativeOverlapped((_, __, ___) => { }, (object)null, new byte[0]);

                object result = ThreadPoolBoundHandle.GetNativeOverlappedState(overlapped);

                Assert.Null(result);

                boundHandle.FreeNativeOverlapped(overlapped);
            }
        }
    }
示例#7
0
        // Using RunContinuationsAsynchronously for compat reasons (old API used ThreadPool.QueueUserWorkItem for continuations)
        protected PipeCompletionSource(ThreadPoolBoundHandle handle, CancellationToken cancellationToken, object pinData)
            : base(TaskCreationOptions.RunContinuationsAsynchronously)
        {
            Debug.Assert(handle != null, "handle is null");

            _threadPoolBinding = handle;
            _cancellationToken = cancellationToken;
            _state             = NoResult;

            _overlapped = _threadPoolBinding.AllocateNativeOverlapped((errorCode, numBytes, pOverlapped) =>
            {
                var completionSource = (PipeCompletionSource <TResult>)ThreadPoolBoundHandle.GetNativeOverlappedState(pOverlapped);
                Debug.Assert(completionSource.Overlapped == pOverlapped);

                completionSource.AsyncCallback(errorCode, numBytes);
            }, this, pinData);
        }
示例#8
0
        // Using RunContinuationsAsynchronously for compat reasons (old API used ThreadPool.QueueUserWorkItem for continuations)
        protected PipeCompletionSource(ThreadPoolBoundHandle handle, ReadOnlyMemory <byte> bufferToPin)
            : base(TaskCreationOptions.RunContinuationsAsynchronously)
        {
            Debug.Assert(handle != null, "handle is null");

            _threadPoolBinding = handle;
            _state             = NoResult;

            _pinnedMemory = bufferToPin.Pin();
            _overlapped   = _threadPoolBinding.AllocateNativeOverlapped((errorCode, numBytes, pOverlapped) =>
            {
                var completionSource = (PipeCompletionSource <TResult>)ThreadPoolBoundHandle.GetNativeOverlappedState(pOverlapped);
                Debug.Assert(completionSource.Overlapped == pOverlapped);

                completionSource.AsyncCallback(errorCode, numBytes);
            }, this, null);
        }
示例#9
0
    public unsafe void AllocateNativeOverlapped_PreAllocated_WhenAlreadyAllocated_ThrowsArgumentException()
    {
        using (ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle())
        {
            using (PreAllocatedOverlapped preAlloc = new PreAllocatedOverlapped(delegate { }, null, null))
            {
                NativeOverlapped *overlapped = handle.AllocateNativeOverlapped(preAlloc);

                Assert.Throws <ArgumentException>(() =>
                {
                    handle.AllocateNativeOverlapped(preAlloc);
                });

                handle.FreeNativeOverlapped(overlapped);
            }
        }
    }
    [PlatformSpecific(TestPlatforms.Windows)] // ThreadPoolBoundHandle.BindHandle is not supported on Unix
    public unsafe void FreeNativeOverlapped_WithWrongHandle_ThrowsArgumentException()
    {
        using (ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle())
        {
            NativeOverlapped *overlapped = handle.AllocateNativeOverlapped((_, __, ___) => { }, (object)null, (byte[])null);

            using (ThreadPoolBoundHandle handle2 = CreateThreadPoolBoundHandle())
            {
                Assert.Throws <ArgumentException>(() =>
                {
                    handle2.FreeNativeOverlapped(overlapped);
                });
            }

            handle.FreeNativeOverlapped(overlapped);
        }
    }
示例#11
0
        // Win32 file channel impl
        // TODO: Other platforms
        public unsafe void OpenReadFile(string path)
        {
            var fileHandle = CreateFile(path, FileAccess.Read, FileShare.Read, IntPtr.Zero, FileMode.Open, EFileAttributes.Overlapped, IntPtr.Zero);

            var handle = ThreadPoolBoundHandle.BindHandle(fileHandle);

            var readOperation = new ReadOperation
            {
                Channel    = _channel,
                FileHandle = fileHandle,
                Handle     = handle,
                IOCallback = IOCallback
            };

            _channel.OnStartReading(readOperation.Read);
            _channel.OnDispose(fileHandle.Dispose);
        }
示例#12
0
        internal RequestQueue(UrlGroup urlGroup)
        {
            _urlGroup = urlGroup;

            var queueName = "IISConsole";
            HttpRequestQueueV2Handle requestQueueHandle = null;

            var statusCode = HttpApi.HttpCreateRequestQueue(
                HttpApi.Version, queueName, null, HttpApiTypes.HTTP_CREATE_REQUEST_QUEUE_FLAGS.HTTP_CREATE_REQUEST_QUEUE_FLAG_CONTROLLER, out requestQueueHandle);

            if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS)
            {
                throw new HttpSysException((int)statusCode);
            }

            Handle      = requestQueueHandle;
            BoundHandle = ThreadPoolBoundHandle.BindHandle(Handle);
        }
    public unsafe void GetNativeOverlappedState_WhenUnderlyingStateIsObject_ReturnsObject()
    {
        object context = new object();

        using (SafeHandle handle = HandleFactory.CreateAsyncFileHandleForWrite())
        {
            using (ThreadPoolBoundHandle boundHandle = ThreadPoolBoundHandle.BindHandle(handle))
            {
                NativeOverlapped *overlapped = boundHandle.AllocateNativeOverlapped((_, __, ___) => { }, context, new byte[0]);

                object result = ThreadPoolBoundHandle.GetNativeOverlappedState(overlapped);

                Assert.Same(context, result);

                boundHandle.FreeNativeOverlapped(overlapped);
            }
        }
    }
示例#14
0
        // Binds the Socket Win32 Handle to the ThreadPool's CompletionPort.
        public ThreadPoolBoundHandle GetOrAllocateThreadPoolBoundHandle()
        {
            if (_released)
            {
                // Keep the exception message pointing at the external type.
                throw new ObjectDisposedException(typeof(Socket).FullName);
            }

            // Check to see if the socket native _handle is already
            // bound to the ThreadPool's completion port.
            if (_iocpBoundHandle == null)
            {
                lock (_iocpBindingLock)
                {
                    if (_iocpBoundHandle == null)
                    {
                        // Bind the socket native _handle to the ThreadPool.
                        if (GlobalLog.IsEnabled)
                        {
                            GlobalLog.Print("SafeCloseSocket#" + LoggingHash.HashString(this) + "::BindToCompletionPort() calling ThreadPool.BindHandle()");
                        }

                        try
                        {
                            // The handle (this) may have been already released:
                            // E.g.: The socket has been disposed in the main thread. A completion callback may
                            //       attempt starting another operation.
                            _iocpBoundHandle = ThreadPoolBoundHandle.BindHandle(this);
                        }
                        catch (Exception exception)
                        {
                            if (ExceptionCheck.IsFatal(exception))
                            {
                                throw;
                            }
                            CloseAsIs();
                            throw;
                        }
                    }
                }
            }

            return(_iocpBoundHandle);
        }
    [PlatformSpecific(TestPlatforms.Windows)] // ThreadPoolBoundHandle.BindHandle is not supported on Unix
    public unsafe void AllocateNativeOverlapped_BlittableTypeAsPinData_DoesNotThrow()
    {
        using (ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle())
        {
            NativeOverlapped *result = handle.AllocateNativeOverlapped((_, __, ___) => { }, new object(), new BlittableType()
            {
                i = 42
            });
            Assert.True(result != null);
            handle.FreeNativeOverlapped(result);

            result = handle.UnsafeAllocateNativeOverlapped((_, __, ___) => { }, new object(), new BlittableType()
            {
                i = 42
            });
            Assert.True(result != null);
            handle.FreeNativeOverlapped(result);
        }
    }
示例#16
0
    public unsafe void AllocateNativeOverlapped_ObjectArrayAsPinData_DoesNotThrow()
    {
        object[] 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);
        }
    }
            // Using RunContinuationsAsynchronously for compat reasons (old API used Task.Factory.StartNew for continuations)
            internal FileStreamCompletionSource(int numBufferedBytes, byte[] bytes, ThreadPoolBoundHandle handle, CancellationToken cancellationToken)
                : base(TaskCreationOptions.RunContinuationsAsynchronously)
            {
                _numBufferedBytes  = numBufferedBytes;
                _handle            = handle;
                _result            = NoResult;
                _cancellationToken = cancellationToken;

                // Create a managed overlapped class
                // We will set the file offsets later
                var ioCallback = s_IOCallback; // cached static delegate; delay initialized due to it being SecurityCritical

                if (ioCallback == null)
                {
                    s_IOCallback = ioCallback = new IOCompletionCallback(AsyncFSCallback);
                }
                _overlapped = handle.AllocateNativeOverlapped(ioCallback, this, bytes);
                Debug.Assert(_overlapped != null, "Did Overlapped.Pack or Overlapped.UnsafePack just return a null?");
            }
示例#18
0
        private Interop.HttpApi.HTTP_REQUEST *Allocate(ThreadPoolBoundHandle boundHandle, uint size)
        {
            uint newSize = size != 0 ? size : RequestBuffer == null ? 4096 : Size;

            if (_nativeOverlapped != null && newSize != RequestBuffer.Length)
            {
                NativeOverlapped *nativeOverlapped = _nativeOverlapped;
                _nativeOverlapped = null;
                _boundHandle.FreeNativeOverlapped(nativeOverlapped);
            }
            if (_nativeOverlapped == null)
            {
                SetBuffer(checked ((int)newSize));
                _boundHandle      = boundHandle;
                _nativeOverlapped = boundHandle.AllocateNativeOverlapped(ListenerAsyncResult.IOCallback, state: _result, pinData: RequestBuffer);
                return((Interop.HttpApi.HTTP_REQUEST *)Marshal.UnsafeAddrOfPinnedArrayElement(RequestBuffer, 0));
            }
            return(RequestBlob);
        }
    [PlatformSpecific(TestPlatforms.Windows)] // ThreadPoolBoundHandle.BindHandle is not supported on Unix
    public unsafe void GetNativeOverlappedState_WhenUnderlyingStateIsIAsyncResult_ReturnsIAsyncResult()
    {                                         // CoreCLR/Desktop CLR version of overlapped sits on top of Overlapped class
        // and treats IAsyncResult specially, which is why we special case this case.

        AsyncResult context = new AsyncResult();

        using (SafeHandle handle = HandleFactory.CreateAsyncFileHandleForWrite(GetTestFilePath()))
        {
            using (ThreadPoolBoundHandle boundHandle = ThreadPoolBoundHandle.BindHandle(handle))
            {
                NativeOverlapped *overlapped = boundHandle.AllocateNativeOverlapped((_, __, ___) => { }, context, new byte[0]);

                object result = ThreadPoolBoundHandle.GetNativeOverlappedState(overlapped);

                Assert.Same(context, result);

                boundHandle.FreeNativeOverlapped(overlapped);
            }
        }
    }
示例#20
0
        private void FreeNativeOverlapped()
        {
            // Do not call free during AppDomain shutdown, there may be an outstanding operation.
            // Overlapped will take care calling free when the native callback completes.
            IntPtr oldHandle = Interlocked.Exchange(ref handle, IntPtr.Zero);

            if (oldHandle != IntPtr.Zero && !Environment.HasShutdownStarted)
            {
                unsafe
                {
                    Debug.Assert(_socketHandle != null, "_socketHandle is null.");

                    ThreadPoolBoundHandle boundHandle = _socketHandle.IOCPBoundHandle;
                    Debug.Assert(boundHandle != null, "SafeNativeOverlapped::FreeNativeOverlapped - boundHandle is null");

                    // FreeNativeOverlapped will be called even if boundHandle was previously disposed.
                    boundHandle?.FreeNativeOverlapped((NativeOverlapped *)oldHandle);
                }
            }
        }
        // Using RunContinuationsAsynchronously for compat reasons (old API used ThreadPool.QueueUserWorkItem for continuations)
        internal ConnectionCompletionSource(NamedPipeServerStream server, CancellationToken cancellationToken)
            : base(TaskCreationOptions.RunContinuationsAsynchronously)
        {
            Debug.Assert(server != null, "server is null");
            Debug.Assert(server._threadPoolBinding != null, "server._threadPoolBinding is null");

            _threadPoolBinding = server._threadPoolBinding;
            _serverStream      = server;
            _cancellationToken = cancellationToken;

            _overlapped = _threadPoolBinding.AllocateNativeOverlapped((errorCode, numBytes, pOverlapped) =>
            {
                var completionSource = (ConnectionCompletionSource)ThreadPoolBoundHandle.GetNativeOverlappedState(pOverlapped);
                Debug.Assert(completionSource.Overlapped == pOverlapped);

                completionSource.AsyncCallback(errorCode, numBytes);
            }, this, null);

            _state = NoResult;
        }
示例#22
0
    public unsafe void AllocateNativeOverlapped_PossibleReusedReturnedNativeOverlapped_OffsetLowAndOffsetHighSetToZero()
    {   // The CLR reuses NativeOverlapped underneath, check to make sure that they reset fields back to zero
        using (ThreadPoolBoundHandle handle = CreateThreadPoolBoundHandle())
        {
            NativeOverlapped *overlapped = handle.AllocateNativeOverlapped((_, __, ___) => { }, new object(), new byte[256]);
            overlapped->OffsetHigh = 1;
            overlapped->OffsetLow  = 1;
            handle.FreeNativeOverlapped(overlapped);

            overlapped = 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);
        }
    }
示例#23
0
        public unsafe static void IOCallback(uint errorCode, uint numBytes, NativeOverlapped *pOverlapped)
        {
            var state     = ThreadPoolBoundHandle.GetNativeOverlappedState(pOverlapped);
            var operation = (ReadOperation)state;

            operation.Offset += (int)numBytes;

            var iterator = operation.Iterator.Value;

            iterator.UpdateEnd((int)numBytes);
            operation.Channel.EndWriteAsync(iterator);

            if (numBytes == 0)
            {
                operation.Channel.CompleteWriting();
            }
            else
            {
                operation.Read();
            }
        }
        private void StartRaisingEvents()
        {
            // If we're attached, don't do anything.
            if (!IsHandleInvalid)
            {
                return;
            }

            // Create handle to directory being monitored
            _directoryHandle = NativeMethods.CreateFile(_directory,                              // Directory name
                                                        UnsafeNativeMethods.FILE_LIST_DIRECTORY, // access (read-write) mode
                                                        UnsafeNativeMethods.FILE_SHARE_READ |
                                                        UnsafeNativeMethods.FILE_SHARE_DELETE |
                                                        UnsafeNativeMethods.FILE_SHARE_WRITE,     // share mode
                                                        null,                                     // security descriptor
                                                        UnsafeNativeMethods.OPEN_EXISTING,        // how to create
                                                        UnsafeNativeMethods.FILE_FLAG_BACKUP_SEMANTICS |
                                                        UnsafeNativeMethods.FILE_FLAG_OVERLAPPED, // file attributes
                                                        new SafeFileHandle(IntPtr.Zero, false)    // file with attributes to copy
                                                        );

            if (IsHandleInvalid)
            {
                throw new FileNotFoundException(SR.Format(SR.FSW_IOError, _directory));
            }

            _stopListening = false;
            // Start ignoring all events that were initiated before this.
            Interlocked.Increment(ref _currentSession);

            // Attach handle to thread pool

            _threadPoolBinding = ThreadPoolBoundHandle.BindHandle(_directoryHandle);
            _enabled           = true;

            // Setup IO completion port
            Monitor(null);
        }
示例#25
0
        public unsafe static void IOCallback(uint errorCode, uint numBytes, NativeOverlapped *pOverlapped)
        {
            var state     = ThreadPoolBoundHandle.GetNativeOverlappedState(pOverlapped);
            var operation = (ReadOperation)state;

            operation.ThreadPoolBoundHandle.FreeNativeOverlapped(operation.Overlapped);

            operation.Offset += (int)numBytes;

            var buffer = operation.BoxedBuffer.Value;

            buffer.CommitBytes((int)numBytes);
            operation.Channel.WriteAsync(buffer);

            if (numBytes == 0)
            {
                operation.Channel.CompleteWriting();
            }
            else
            {
                operation.Read();
            }
        }
        // Win32 file channel impl
        // TODO: Other platforms
        public unsafe void OpenReadFile(string path)
        {
            var fileHandle = CreateFile(path, FileAccess.Read, FileShare.Read, IntPtr.Zero, FileMode.Open, EFileAttributes.Overlapped, IntPtr.Zero);

            var handle = ThreadPoolBoundHandle.BindHandle(fileHandle);

            var readOperation = new ReadOperation
            {
                Channel               = _channel,
                FileHandle            = fileHandle,
                ThreadPoolBoundHandle = handle,
                IOCallback            = IOCallback
            };

            var overlapped = new PreAllocatedOverlapped(IOCallback, readOperation, null);

            readOperation.PreAllocatedOverlapped = overlapped;

            _channel.ReadingStarted.ContinueWith((t, state) =>
            {
                ((ReadOperation)state).Read();
            },
                                                 readOperation);
        }
示例#27
0
        // Win32 file impl
        // TODO: Other platforms
        public unsafe void OpenReadFile(string path)
        {
            var fileHandle = CreateFile(path, FileAccess.Read, FileShare.Read, IntPtr.Zero, FileMode.Open, EFileAttributes.Overlapped, IntPtr.Zero);

            var handle = ThreadPoolBoundHandle.BindHandle(fileHandle);

            var readOperation = new ReadOperation
            {
                Writer                = _writer,
                FileHandle            = fileHandle,
                ThreadPoolBoundHandle = handle,
                IOCallback            = IOCallback
            };

            var overlapped = new PreAllocatedOverlapped(IOCallback, readOperation, null);

            readOperation.PreAllocatedOverlapped = overlapped;

            Task.Factory.StartNew(state =>
            {
                ((ReadOperation)state).Read();
            },
                                  readOperation);
        }
        private Interop.HttpApi.HTTP_REQUEST *Allocate(ThreadPoolBoundHandle boundHandle, uint size)
        {
            uint newSize = size != 0 ? size : RequestBuffer == IntPtr.Zero ? 4096 : Size;

            if (_nativeOverlapped != null)
            {
#if DEBUG
                DebugRefCountReleaseNativeOverlapped();
#endif

                NativeOverlapped *nativeOverlapped = _nativeOverlapped;
                _nativeOverlapped = null;
                _boundHandle !.FreeNativeOverlapped(nativeOverlapped);
            }

#if DEBUG
            DebugRefCountAllocNativeOverlapped();
#endif
            SetBuffer(checked ((int)newSize));
            _boundHandle      = boundHandle;
            _nativeOverlapped = boundHandle.AllocateNativeOverlapped(ListenerAsyncResult.IOCallback, state: _result, pinData: RequestBuffer);

            return((Interop.HttpApi.HTTP_REQUEST *)RequestBuffer.ToPointer());
        }
 public void BindHandle_ValidHandle_ThrowsPlatformNotSupportedException()
 {
     Assert.Throws <PlatformNotSupportedException>(() => ThreadPoolBoundHandle.BindHandle(new Win32Handle(new IntPtr(1))));
 }
        private static unsafe void Callback(uint errorCode, uint numBytes, NativeOverlapped *nativeOverlapped)
        {
            var asyncResult = (RequestStreamAsyncResult)ThreadPoolBoundHandle.GetNativeOverlappedState(nativeOverlapped);

            IOCompleted(asyncResult, errorCode, numBytes);
        }