1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
5 namespace System.Threading
8 /// Represents pre-allocated state for native overlapped I/O operations.
10 /// <seealso cref="ThreadPoolBoundHandle.AllocateNativeOverlapped(PreAllocatedOverlapped)"/>
11 public sealed class PreAllocatedOverlapped : IDisposable, IDeferredDisposable
13 internal readonly ThreadPoolBoundHandleOverlapped _overlapped;
14 private DeferredDisposableLifetime<PreAllocatedOverlapped> _lifetime;
17 /// Initializes a new instance of the <see cref="PreAllocatedOverlapped"/> class, specifying
18 /// a delegate that is invoked when each asynchronous I/O operation is complete, a user-provided
19 /// object providing context, and managed objects that serve as buffers.
21 /// <param name="callback">
22 /// An <see cref="IOCompletionCallback"/> delegate that represents the callback method
23 /// invoked when each asynchronous I/O operation completes.
25 /// <param name="state">
26 /// A user-provided object that distinguishes <see cref="NativeOverlapped"/> instance produced from this
27 /// object from other <see cref="NativeOverlapped"/> instances. Can be <see langword="null"/>.
29 /// <param name="pinData">
30 /// An object or array of objects representing the input or output buffer for the operations. Each
31 /// object represents a buffer, for example an array of bytes. Can be <see langword="null"/>.
34 /// The new <see cref="PreAllocatedOverlapped"/> instance can be passed to
35 /// <see cref="ThreadPoolBoundHandle.AllocateNativeOverlapped(PreAllocatedOverlapped)"/>, to produce
36 /// a <see cref="NativeOverlapped"/> instance that can be passed to the operating system in overlapped
37 /// I/O operations. A single <see cref="PreAllocatedOverlapped"/> instance can only be used for
38 /// a single native I/O operation at a time. However, the state stored in the <see cref="PreAllocatedOverlapped"/>
39 /// instance can be reused for subsequent native operations.
41 /// The buffers specified in <paramref name="pinData"/> are pinned until <see cref="Dispose"/> is called.
44 /// <exception cref="ArgumentNullException">
45 /// <paramref name="callback"/> is <see langword="null"/>.
47 /// <exception cref="ObjectDisposedException">
48 /// This method was called after the <see cref="ThreadPoolBoundHandle"/> was disposed.
50 public unsafe PreAllocatedOverlapped(IOCompletionCallback callback, object state, object pinData)
53 throw new ArgumentNullException(nameof(callback));
55 _overlapped = new ThreadPoolBoundHandleOverlapped(callback, state, pinData, this);
58 internal bool AddRef()
60 return _lifetime.AddRef(this);
63 internal void Release()
65 _lifetime.Release(this);
69 /// Frees the resources associated with this <see cref="PreAllocatedOverlapped"/> instance.
71 public unsafe void Dispose()
73 _lifetime.Dispose(this);
74 GC.SuppressFinalize(this);
77 ~PreAllocatedOverlapped()
80 // During shutdown, don't automatically clean up, because this instance may still be
81 // reachable/usable by other code.
83 if (!Environment.HasShutdownStarted)
87 unsafe void IDeferredDisposable.OnFinalRelease(bool disposed)
89 if (_overlapped != null)
93 Overlapped.Free(_overlapped._nativeOverlapped);
97 _overlapped._boundHandle = null;
98 _overlapped._completed = false;
99 *_overlapped._nativeOverlapped = default(NativeOverlapped);