// 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 { /// /// Represents pre-allocated state for native overlapped I/O operations. /// /// public sealed class PreAllocatedOverlapped : IDisposable, IDeferredDisposable { internal readonly ThreadPoolBoundHandleOverlapped _overlapped; private DeferredDisposableLifetime _lifetime; /// /// Initializes a new instance of the 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. /// /// /// An delegate that represents the callback method /// invoked when each asynchronous I/O operation completes. /// /// /// A user-provided object that distinguishes instance produced from this /// object from other instances. Can be . /// /// /// 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 . /// /// /// The new instance can be passed to /// , to produce /// a instance that can be passed to the operating system in overlapped /// I/O operations. A single instance can only be used for /// a single native I/O operation at a time. However, the state stored in the /// instance can be reused for subsequent native operations. /// /// The buffers specified in are pinned until is called. /// /// /// /// is . /// /// /// This method was called after the was disposed. /// 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); } /// /// Frees the resources associated with this instance. /// 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); } } } } }