diff options
author | Jiyoung Yun <jy910.yun@samsung.com> | 2016-11-23 19:09:09 +0900 |
---|---|---|
committer | Jiyoung Yun <jy910.yun@samsung.com> | 2016-11-23 19:09:09 +0900 |
commit | 4b4aad7217d3292650e77eec2cf4c198ea9c3b4b (patch) | |
tree | 98110734c91668dfdbb126fcc0e15ddbd93738ca /src/mscorlib/src/System/WeakReferenceOfT.cs | |
parent | fa45f57ed55137c75ac870356a1b8f76c84b229c (diff) | |
download | coreclr-4b4aad7217d3292650e77eec2cf4c198ea9c3b4b.tar.gz coreclr-4b4aad7217d3292650e77eec2cf4c198ea9c3b4b.tar.bz2 coreclr-4b4aad7217d3292650e77eec2cf4c198ea9c3b4b.zip |
Imported Upstream version 1.1.0upstream/1.1.0
Diffstat (limited to 'src/mscorlib/src/System/WeakReferenceOfT.cs')
-rw-r--r-- | src/mscorlib/src/System/WeakReferenceOfT.cs | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/src/mscorlib/src/System/WeakReferenceOfT.cs b/src/mscorlib/src/System/WeakReferenceOfT.cs new file mode 100644 index 0000000000..b8195df6d9 --- /dev/null +++ b/src/mscorlib/src/System/WeakReferenceOfT.cs @@ -0,0 +1,121 @@ +// 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. + +/*============================================================ +** +** +** Purpose: A wrapper for establishing a WeakReference to a generic type. +** +===========================================================*/ +namespace System +{ + using System; + using System.Runtime.Serialization; + using System.Security; + using System.Runtime; + using System.Runtime.CompilerServices; + using System.Runtime.Versioning; + using System.Diagnostics.Contracts; + + [Serializable] + // This class is sealed to mitigate security issues caused by Object::MemberwiseClone. + public sealed class WeakReference<T> : ISerializable + where T : class + { + // If you fix bugs here, please fix them in WeakReference at the same time. + + // This field is not a regular GC handle. It can have a special values that are used to prevent a race condition between setting the target and finalization. + internal IntPtr m_handle; + + // Creates a new WeakReference that keeps track of target. + // Assumes a Short Weak Reference (ie TrackResurrection is false.) + // + public WeakReference(T target) + : this(target, false) + { + } + + //Creates a new WeakReference that keeps track of target. + // + public WeakReference(T target, bool trackResurrection) + { + Create(target, trackResurrection); + } + + internal WeakReference(SerializationInfo info, StreamingContext context) + { + if (info == null) { + throw new ArgumentNullException("info"); + } + Contract.EndContractBlock(); + + T target = (T)info.GetValue("TrackedObject", typeof(T)); + bool trackResurrection = info.GetBoolean("TrackResurrection"); + + Create(target, trackResurrection); + } + + // + // We are exposing TryGetTarget instead of a simple getter to avoid a common problem where people write incorrect code like: + // + // WeakReference ref = ...; + // if (ref.Target != null) + // DoSomething(ref.Target) + // + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public bool TryGetTarget(out T target) + { + // Call the worker method that has more performant but less user friendly signature. + T o = this.Target; + target = o; + return o != null; + } + + public void SetTarget(T target) + { + this.Target = target; + } + + // This is property for better debugging experience (VS debugger shows values of properties when you hover over the variables) + private extern T Target + { + [MethodImplAttribute(MethodImplOptions.InternalCall)] + [SecuritySafeCritical] + get; + [MethodImplAttribute(MethodImplOptions.InternalCall)] + [SecuritySafeCritical] + set; + } + + // Free all system resources associated with this reference. + // + // Note: The WeakReference<T> finalizer is not usually run, but + // treated specially in gc.cpp's ScanForFinalization + // This is needed for subclasses deriving from WeakReference<T>, however. + // Additionally, there may be some cases during shutdown when we run this finalizer. + [MethodImplAttribute(MethodImplOptions.InternalCall)] + [SecuritySafeCritical] + extern ~WeakReference(); + + [SecurityCritical] + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + if (info == null) { + throw new ArgumentNullException("info"); + } + Contract.EndContractBlock(); + + info.AddValue("TrackedObject", this.Target, typeof(T)); + info.AddValue("TrackResurrection", IsTrackResurrection()); + } + + [MethodImplAttribute(MethodImplOptions.InternalCall)] + [SecuritySafeCritical] + private extern void Create(T target, bool trackResurrection); + + [MethodImplAttribute(MethodImplOptions.InternalCall)] + [SecuritySafeCritical] + private extern bool IsTrackResurrection(); + } +} |