File: system\iappdomainpausemanager.cs
Project: ndp\clr\src\bcl\mscorlib.csproj (mscorlib)
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
/*=============================================================================
**
** Class: System.IAppDomainPauseConsumer and its implementation
**
** Purpose: Interface meant for CLR to participate in framework rundown.
** AppDomainPauseManager is the class that encapsulates all Fx rundown work.
**
** Copyright (c) Microsoft
**
=============================================================================*/
 
namespace System
{
    using System;
    using System.Threading;
    using System.Security;
    using System.Diagnostics.Contracts;
    using System.Runtime.Versioning;
    using System.Runtime.CompilerServices;
 
#if FEATURE_LEGACYNETCFFAS
    [System.Security.SecurityCritical]
    public interface IAppDomainPauseManager
    {
        void Pausing();
        void Paused();
        void Resuming();
        void Resumed();
    }
#endif
 
    [System.Security.SecurityCritical]
#if FEATURE_LEGACYNETCFFAS
    public class AppDomainPauseManager : IAppDomainPauseManager
#else
    internal class AppDomainPauseManager
#endif
    {
        [System.Security.SecurityCritical]
        public AppDomainPauseManager()
        {
            isPaused = false;
        }
 
        [System.Security.SecurityCritical]
        static AppDomainPauseManager()
        {
        }
        
        static readonly AppDomainPauseManager instance = new AppDomainPauseManager();
        internal static AppDomainPauseManager Instance
        {
            [System.Security.SecurityCritical]
            get { return instance; }
        }
 
        // FAS: IAppDomainPauseConsumer interface implementation
        // currently there is nothing we do here as the implementation
        // of updating pause times have been moved to native CorHost2
        [System.Security.SecurityCritical]
        public void Pausing()
        {
        }
 
        [System.Security.SecurityCritical]
        public void Paused()
        {
            Contract.Assert(!isPaused);
 
            if(ResumeEvent == null)
                ResumeEvent = new ManualResetEvent(false);
            else
                ResumeEvent.Reset();
 
            Timer.Pause();
 
            // Set IsPaused at the last as other threads seeing it set, will expect a valid
            // reset ResumeEvent. Also the requirement here is that only after Paused
            // returns other threads should block on this event. So there is ---- here.
            isPaused = true;
        }
 
        [System.Security.SecurityCritical]
        public void Resuming()
        {
            Contract.Assert(isPaused);
            isPaused = false;
            ResumeEvent.Set();
        }
 
        [System.Security.SecurityCritical]
        public void Resumed()
        {
            Timer.Resume();
        }
   
        private static volatile bool isPaused;
 
        internal static bool IsPaused
        {
            [System.Security.SecurityCritical]
            get { return isPaused; }
        }
 
        internal static ManualResetEvent ResumeEvent
        {
            [System.Security.SecurityCritical]
            get; 
            [System.Security.SecurityCritical]
            set;
        }
    }
}