|
9 | 9 | namespace System.Runtime |
10 | 10 | { |
11 | 11 | /// <summary> |
12 | | - /// Represents a dependent GC handle, which will conditionally keep a dependent object instance alive |
13 | | - /// as long as a target object instance is alive as well, without representing a strong reference to the |
14 | | - /// target object instance. That is, a <see cref="DependentHandle"/> value with a given object instance as |
15 | | - /// target will not cause the target to be kept alive if there are no other strong references to it, but |
16 | | - /// it will do so for the dependent object instance as long as the target is alive. |
17 | | - /// <para> |
18 | | - /// This type is conceptually equivalent to having a weak reference to a given target object instance A, with |
19 | | - /// that object having a field or property (or some other strong reference) to a dependent object instance B. |
20 | | - /// </para> |
| 12 | + /// Represents a dependent GC handle, which will conditionally keep a dependent object instance alive as long as |
| 13 | + /// a target object instance is alive as well, without representing a strong reference to the target instance. |
21 | 14 | /// </summary> |
22 | 15 | /// <remarks> |
| 16 | + /// A <see cref="DependentHandle"/> value with a given object instance as target will not cause the target |
| 17 | + /// to be kept alive if there are no other strong references to it, but it will do so for the dependent |
| 18 | + /// object instance as long as the target is alive. |
| 19 | + /// <para> |
| 20 | + /// Using this type is conceptually equivalent to having a weak reference to a given target object instance A, |
| 21 | + /// with that object having a field or property (or some other strong reference) to a dependent object instance B. |
| 22 | + /// </para> |
| 23 | + /// <para> |
23 | 24 | /// The <see cref="DependentHandle"/> type is not thread-safe, and consumers are responsible for ensuring that |
24 | 25 | /// <see cref="Dispose"/> is not called concurrently with other APIs. Not doing so results in undefined behavior. |
25 | | - /// <para>The <see cref="Target"/> and <see cref="Dependent"/> properties are instead thread-safe.</para> |
| 26 | + /// </para> |
| 27 | + /// <para> |
| 28 | + /// The <see cref="IsAllocated"/>, <see cref="Target"/>, <see cref="Dependent"/> and <see cref="TargetAndDependent"/> |
| 29 | + /// properties are instead thread-safe, and safe to use if <see cref="Dispose"/> is not concurrently invoked as well. |
| 30 | + /// </para> |
26 | 31 | /// </remarks> |
27 | 32 | public struct DependentHandle : IDisposable |
28 | 33 | { |
@@ -60,13 +65,15 @@ public struct DependentHandle : IDisposable |
60 | 65 | /// <param name="dependent">The dependent object instance to associate with <paramref name="target"/>.</param> |
61 | 66 | public DependentHandle(object? target, object? dependent) |
62 | 67 | { |
63 | | - // no need to check for null result: nInitialize expected to throw OOM. |
| 68 | + // no need to check for null result: InternalInitialize expected to throw OOM. |
64 | 69 | _handle = InternalInitialize(target, dependent); |
65 | 70 | } |
66 | 71 |
|
67 | 72 | /// <summary> |
68 | | - /// Gets a value indicating whether this handle has been allocated or not. |
| 73 | + /// Gets a value indicating whether this instance was constructed with |
| 74 | + /// <see cref="DependentHandle(object?, object?)"/> and has not yet been disposed. |
69 | 75 | /// </summary> |
| 76 | + /// <remarks>This property is thread-safe.</remarks> |
70 | 77 | public bool IsAllocated => (nint)_handle != 0; |
71 | 78 |
|
72 | 79 | /// <summary> |
@@ -144,11 +151,12 @@ public object? Dependent |
144 | 151 | /// Gets the values of both <see cref="Target"/> and <see cref="Dependent"/> (if available) as an atomic operation. |
145 | 152 | /// That is, even if <see cref="Target"/> is concurrently set to <see langword="null"/>, calling this method |
146 | 153 | /// will either return <see langword="null"/> for both target and dependent, or return both previous values. |
147 | | - /// If <see cref="Target"/> and <see cref="Dependent"/> were used sequentially in this scenario instead, it's |
148 | | - /// could be possible to sometimes successfully retrieve the previous target, but then fail to get the dependent. |
| 154 | + /// If <see cref="Target"/> and <see cref="Dependent"/> were used sequentially in this scenario instead, it |
| 155 | + /// would be possible to sometimes successfully retrieve the previous target, but then fail to get the dependent. |
149 | 156 | /// </summary> |
150 | 157 | /// <returns>The values of <see cref="Target"/> and <see cref="Dependent"/>.</returns> |
151 | 158 | /// <exception cref="InvalidOperationException">Thrown if <see cref="IsAllocated"/> is <see langword="false"/>.</exception> |
| 159 | + /// <remarks>This property is thread-safe.</remarks> |
152 | 160 | public (object? Target, object? Dependent) TargetAndDependent |
153 | 161 | { |
154 | 162 | get |
|
0 commit comments