ContractBase.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / AddIn / AddIn / System / Addin / Pipeline / ContractBase.cs / 1305376 / ContractBase.cs

                            // ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
/*============================================================
** 
** Class:  ContractBase 
**
** Purpose: Provides default implementations of IContract members 
**
===========================================================*/
using System;
using System.Collections.Generic; 
using System.Diagnostics;
using System.Globalization; 
using System.IO; 
using System.Reflection;
using System.AddIn.Contract; 
using System.AddIn;
using System.Runtime.Remoting.Lifetime;
using System.Security.Permissions;
using System.Security; 
using System.Diagnostics.Contracts;
 
namespace System.AddIn.Pipeline 
{
    ///  
    /// Provides default implementations of IContract members
    /// 
    public class ContractBase : MarshalByRefObject, IContract, ISponsor
    { 
        private List m_lifetimeTokens = new List();
        private List m_contractIdentifiers; 
        private readonly Object m_contractIdentifiersLock = new Object(); 
        private Random m_random;
        // flag to indicate that the references that were taken have all been removed; 
        private bool m_zeroReferencesLeft = false;

        private int m_tokenOfAppdomainOwner;
 
        public virtual bool RemoteEquals(IContract contract)
        { 
            return this.Equals(contract); 
        }
 
        public virtual String RemoteToString()
        {
            return this.ToString();
        } 

        public virtual int GetRemoteHashCode() 
        { 
            return this.GetHashCode();
        } 

        //
        // return 'this' if we implement the contract, null otherwise
        // 
        public virtual IContract QueryContract(String contractIdentifier)
        { 
            if (contractIdentifier == null) 
                throw new ArgumentNullException("contractIdentifier");
            System.Diagnostics.Contracts.Contract.EndContractBlock(); 

            if (m_contractIdentifiers == null)
            {
                lock (m_contractIdentifiersLock) 
                {
                    if (m_contractIdentifiers == null) 
                    { 
                        Type t = this.GetType();
                        Type[] interfaces = t.GetInterfaces(); 
                        List identifiers = new List(interfaces.Length);
                        Type typeOfIContract = typeof(IContract);

                        foreach (Type iface in interfaces) 
                        {
                            if (typeOfIContract.IsAssignableFrom(iface)) 
                            { 
                                identifiers.Add(iface.AssemblyQualifiedName);
                            } 
                        }

                        identifiers.Sort();
 
                        System.Threading.Thread.MemoryBarrier();
                        m_contractIdentifiers = identifiers; 
                    } 
                }
            } 

            int i = m_contractIdentifiers.BinarySearch(contractIdentifier);
            return i >= 0 ? this : null;
        } 

        public int AcquireLifetimeToken() 
        { 
            if (m_zeroReferencesLeft)
            { 
                throw new InvalidOperationException(Res.TokenCountZero);
            }

            int next; 

            lock (m_lifetimeTokens) 
            { 
                // Lazily initialize m_random for perf.
                if (m_random == null) 
                {
                    m_random = new Random();
                }
 
                next = m_random.Next();
                while (m_lifetimeTokens.Contains(next)) 
                { 
                    next = m_random.Next();
                } 
                m_lifetimeTokens.Add(next);

                if (m_lifetimeTokens.Count == 1)
                { 
                    // Register as a sponsor the first time a token is aquired.
                    // need to do this here instead of in InitializeLifetimeService because of a bug in remoting 
                    // involving security. 
                    RegisterAsSponsor();
 
                    // Increment ref count on appdomain owner if needed
                    IContract owner = ContractHandle.AppDomainOwner(AppDomain.CurrentDomain);
                    if (owner != null && owner != this)
                    { 
                        m_tokenOfAppdomainOwner = owner.AcquireLifetimeToken();
                    } 
                } 
            }
 
            return next;
        }

        //  
        // 
        //  
        //  
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2129:SecurityTransparentCodeShouldNotReferenceNonpublicSecurityCriticalCode", Justification = "This is a SecurityRules.Level1 assembly, in which this rule is being incorrectly applied")]
        [System.Security.SecuritySafeCritical] 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2128:SecurityTransparentCodeShouldNotAssert", Justification = "This is a SecurityRules.Level1 assembly, in which this rule is being incorrectly applied")]
        public void RevokeLifetimeToken(int token)
        {
 
            lock (m_lifetimeTokens)
            { 
                if (!m_lifetimeTokens.Remove(token)) 
                    throw new InvalidOperationException(Res.LifetimeTokenNotFound);
 
                if (m_lifetimeTokens.Count == 0)
                {
                    m_zeroReferencesLeft = true;
                    // hook to allow subclasses to clean up 
                    OnFinalRevoke();
 
                    IContract owner = ContractHandle.AppDomainOwner(AppDomain.CurrentDomain); 
                    if (owner != null)
                    { 
                        if (owner == this)
                        {
                            // Create a separate thread to unload this appdomain, because we
                            // cannot shut down an appdomain from the Finalizer thread (though there 
                            // is a bug that allows us to do so after the first appdomain has been
                            // unloaded, but let's not rely on that). 
                            // We can consider using an threadpool thread to do this, but that would add 
                            // test burden.
 
                            SecurityPermission permission = new SecurityPermission(SecurityPermissionFlag.ControlThread);
                            permission.Assert();

                            System.Threading.ThreadStart threadDelegate = new System.Threading.ThreadStart(AppDomainUnload); 
                            System.Threading.Thread unloaderThread = new System.Threading.Thread(threadDelegate);
                            unloaderThread.Start(); 
                        } 
                        else
                            owner.RevokeLifetimeToken(m_tokenOfAppdomainOwner); 
                    }
                }
            }
        } 

        // To be overridden if needed. 
        // This is similar to the Dispose pattern, but it is not public. 
        protected virtual void OnFinalRevoke()
        { 
        }

        // 
        //  
        // 
        [System.Security.SecurityCritical] 
        private void AppDomainUnload() 
        {
            // assert is needed for the Internet named permission set. 
            SecurityPermission permission = new SecurityPermission(SecurityPermissionFlag.ControlAppDomain);
            permission.Assert();

            // The AppDomainUnloadedException thrown here will be eaten by the runtime. 
            AppDomain.Unload(AppDomain.CurrentDomain);
        } 
 
        // 
        //  
        // 
        [System.Security.SecurityCritical]
        [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure)]
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Justification="SecurityRules.Level1 assemblies cannot contain Critical code, so they need LinkDemands to protect overridden Critical members from SecurityRules.Level2 assemblies")] 
        public TimeSpan Renewal(ILease lease)
        { 
            if (lease == null) 
                throw new ArgumentNullException("lease");
            System.Diagnostics.Contracts.Contract.EndContractBlock(); 

            lock (m_lifetimeTokens)
            {
                return m_lifetimeTokens.Count > 0 ? lease.InitialLeaseTime : TimeSpan.Zero; 
            }
        } 
 
        // 
        //  
        // 
        // 
        // 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification="Reviewed")] 
        [System.Security.SecuritySafeCritical]
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2128:SecurityTransparentCodeShouldNotAssert", Justification = "This is a SecurityRules.Level1 assembly, in which this rule is being incorrectly applied")] 
        private void RegisterAsSponsor() 
        {
            ILease baseLease = (ILease)GetLifetimeService(); 

            if (baseLease != null)
            {
                // Assert permission to register as a sponsor for this lease.  This is needed for the Internet permission level. 
                SecurityPermission permission = new SecurityPermission(SecurityPermissionFlag.RemotingConfiguration);
                permission.Assert(); 
                try 
                {
                    // register for sponsorship 
                    baseLease.Register(this);
                }
                finally
                { 
                    CodeAccessPermission.RevertAssert();
                } 
            } 
            // baseLease == null when we are not in a separate appdomain
        } 
    }
}


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK