ActionItem.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / System.Runtime.DurableInstancing / System / Runtime / ActionItem.cs / 1305376 / ActionItem.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------

namespace System.Runtime 
{
    using System.Runtime.Diagnostics; 
    using System.Security; 
    using System.Threading;
 
    abstract class ActionItem
    {
        [Fx.Tag.SecurityNote(Critical = "Stores the security context, used later in binding back into")]
        [SecurityCritical] 
        SecurityContext context;
        bool isScheduled; 
 
        bool lowPriority;
 
        protected ActionItem()
        {
        }
 
        public bool LowPriority
        { 
            get 
            {
                return this.lowPriority; 
            }
            protected set
            {
                this.lowPriority = value; 
            }
        } 
 
        public static void Schedule(Action callback, object state)
        { 
            Schedule(callback, state, false);
        }
        [Fx.Tag.SecurityNote(Critical = "Calls into critical method ScheduleCallback",
            Safe = "Schedule invoke of the given delegate under the current context")] 
        [SecuritySafeCritical]
        public static void Schedule(Action callback, object state, bool lowPriority) 
        { 
            Fx.Assert(callback != null, "A null callback was passed for Schedule!");
 
            if (PartialTrustHelpers.ShouldFlowSecurityContext || WaitCallbackActionItem.ShouldUseActivity)
            {
                new DefaultActionItem(callback, state, lowPriority).Schedule();
            } 
            else
            { 
                ScheduleCallback(callback, state, lowPriority); 
            }
        } 

        [Fx.Tag.SecurityNote(Critical = "Called after applying the user context on the stack or (potentially) " +
            "without any user context on the stack")]
        [SecurityCritical] 
        protected abstract void Invoke();
 
        [Fx.Tag.SecurityNote(Critical = "Access critical field context and critical property " + 
            "CallbackHelper.InvokeWithContextCallback, calls into critical method " +
            "PartialTrustHelpers.CaptureSecurityContextNoIdentityFlow, calls into critical method ScheduleCallback; " + 
            "since the invoked method and the capturing of the security contex are de-coupled, can't " +
            "be treated as safe")]
        [SecurityCritical]
        protected void Schedule() 
        {
            if (isScheduled) 
            { 
                throw Fx.Exception.AsError(new InvalidOperationException(SRCore.ActionItemIsAlreadyScheduled));
            } 

            this.isScheduled = true;
            if (PartialTrustHelpers.ShouldFlowSecurityContext)
            { 
                this.context = PartialTrustHelpers.CaptureSecurityContextNoIdentityFlow();
            } 
            if (this.context != null) 
            {
                ScheduleCallback(CallbackHelper.InvokeWithContextCallback); 
            }
            else
            {
                ScheduleCallback(CallbackHelper.InvokeWithoutContextCallback); 
            }
        } 
        [Fx.Tag.SecurityNote(Critical = "Access critical field context and critical property " + 
            "CallbackHelper.InvokeWithContextCallback, calls into critical method ScheduleCallback; " +
            "since nothing is known about the given context, can't be treated as safe")] 
        [SecurityCritical]
        protected void ScheduleWithContext(SecurityContext context)
        {
            if (context == null) 
            {
                throw Fx.Exception.ArgumentNull("context"); 
            } 
            if (isScheduled)
            { 
                throw Fx.Exception.AsError(new InvalidOperationException(SRCore.ActionItemIsAlreadyScheduled));
            }

            this.isScheduled = true; 
            this.context = context.CreateCopy();
            ScheduleCallback(CallbackHelper.InvokeWithContextCallback); 
        } 
        [Fx.Tag.SecurityNote(Critical = "Access critical property CallbackHelper.InvokeWithoutContextCallback, " +
            "Calls into critical method ScheduleCallback; not bound to a security context")] 
        [SecurityCritical]
        protected void ScheduleWithoutContext()
        {
            if (isScheduled) 
            {
                throw Fx.Exception.AsError(new InvalidOperationException(SRCore.ActionItemIsAlreadyScheduled)); 
            } 

            this.isScheduled = true; 
            ScheduleCallback(CallbackHelper.InvokeWithoutContextCallback);
        }

        [Fx.Tag.SecurityNote(Critical = "Calls into critical methods IOThreadScheduler.ScheduleCallbackNoFlow, " + 
            "IOThreadScheduler.ScheduleCallbackLowPriNoFlow")]
        [SecurityCritical] 
        static void ScheduleCallback(Action callback, object state, bool lowPriority) 
        {
            Fx.Assert(callback != null, "Cannot schedule a null callback"); 
            if (lowPriority)
            {
                IOThreadScheduler.ScheduleCallbackLowPriNoFlow(callback, state);
            } 
            else
            { 
                IOThreadScheduler.ScheduleCallbackNoFlow(callback, state); 
            }
        } 

        [Fx.Tag.SecurityNote(Critical = "Extract the security context stored and reset the critical field")]
        [SecurityCritical]
        SecurityContext ExtractContext() 
        {
            Fx.Assert(this.context != null, "Cannot bind to a null context; context should have been set by now"); 
            Fx.Assert(this.isScheduled, "Context is extracted only while the object is scheduled"); 
            SecurityContext result = this.context;
            this.context = null; 
            return result;
        }

        [Fx.Tag.SecurityNote(Critical = "Calls into critical static method ScheduleCallback")] 
        [SecurityCritical]
        void ScheduleCallback(Action callback) 
        { 
            ScheduleCallback(callback, this, this.lowPriority);
        } 

        [SecurityCritical]
        static class CallbackHelper
        { 
            [Fx.Tag.SecurityNote(Critical = "Stores a delegate to a critical method")]
            static Action invokeWithContextCallback; 
            [Fx.Tag.SecurityNote(Critical = "Stores a delegate to a critical method")] 
            static Action invokeWithoutContextCallback;
            [Fx.Tag.SecurityNote(Critical = "Stores a delegate to a critical method")] 
            static ContextCallback onContextAppliedCallback;
            [Fx.Tag.SecurityNote(Critical = "Provides access to a critical field; Initialize it with " +
                "a delegate to a critical method")]
            public static Action InvokeWithContextCallback 
            {
                get 
                { 
                    if (invokeWithContextCallback == null)
                    { 
                        invokeWithContextCallback = new Action(InvokeWithContext);
                    }
                    return invokeWithContextCallback;
                } 
            }
 
            [Fx.Tag.SecurityNote(Critical = "Provides access to a critical field; Initialize it with " + 
                "a delegate to a critical method")]
            public static Action InvokeWithoutContextCallback 
            {
                get
                {
                    if (invokeWithoutContextCallback == null) 
                    {
                        invokeWithoutContextCallback = new Action(InvokeWithoutContext); 
                    } 
                    return invokeWithoutContextCallback;
                } 
            }
            [Fx.Tag.SecurityNote(Critical = "Provides access to a critical field; Initialize it with " +
                "a delegate to a critical method")]
            public static ContextCallback OnContextAppliedCallback 
            {
                get 
                { 
                    if (onContextAppliedCallback == null)
                    { 
                        onContextAppliedCallback = new ContextCallback(OnContextApplied);
                    }
                    return onContextAppliedCallback;
                } 
            }
            [Fx.Tag.SecurityNote(Critical = "Called by the scheduler without any user context on the stack")] 
            static void InvokeWithContext(object state) 
            {
                SecurityContext context = ((ActionItem)state).ExtractContext(); 
                SecurityContext.Run(context, OnContextAppliedCallback, state);
            }

            [Fx.Tag.SecurityNote(Critical = "Called by the scheduler without any user context on the stack")] 
            static void InvokeWithoutContext(object state)
            { 
                ((ActionItem)state).Invoke(); 
                ((ActionItem)state).isScheduled = false;
            } 
            [Fx.Tag.SecurityNote(Critical = "Called after applying the user context on the stack")]
            static void OnContextApplied(object o)
            {
                ((ActionItem)o).Invoke(); 
                ((ActionItem)o).isScheduled = false;
            } 
        } 

        class DefaultActionItem : ActionItem 
        {
            [Fx.Tag.SecurityNote(Critical = "Stores a delegate that will be called later, at a particular context")]
            [SecurityCritical]
            Action callback; 
            [Fx.Tag.SecurityNote(Critical = "Stores an object that will be passed to the delegate that will be " +
                "called later, at a particular context")] 
            [SecurityCritical] 
            object state;
 
            bool flowActivityId;
            Guid activityId;

            [Fx.Tag.SecurityNote(Critical = "Access critical fields callback and state", 
                Safe = "Doesn't leak information or resources")]
            [SecuritySafeCritical] 
            public DefaultActionItem(Action callback, object state, bool isLowPriority) 
            {
                Fx.Assert(callback != null, "Shouldn't instantiate an object to wrap a null callback"); 
                base.LowPriority = isLowPriority;
                this.callback = callback;
                this.state = state;
                if (WaitCallbackActionItem.ShouldUseActivity) 
                {
                    this.flowActivityId = true; 
                    this.activityId = DiagnosticTrace.ActivityId; 
                }
            } 

            [Fx.Tag.SecurityNote(Critical = "Implements a the critical abstract ActionItem.Invoke method, " +
                "Access critical fields callback and state")]
            [SecurityCritical] 
            protected override void Invoke()
            { 
                if (this.flowActivityId) 
                {
                    Guid currentActivityId = DiagnosticTrace.ActivityId; 
                    try
                    {
                        DiagnosticTrace.ActivityId = this.activityId;
                        this.callback(this.state); 
                    }
                    finally 
                    { 
                        DiagnosticTrace.ActivityId = currentActivityId;
                    } 
                }
                else
                {
                    this.callback(this.state); 
                }
            } 
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------

namespace System.Runtime 
{
    using System.Runtime.Diagnostics; 
    using System.Security; 
    using System.Threading;
 
    abstract class ActionItem
    {
        [Fx.Tag.SecurityNote(Critical = "Stores the security context, used later in binding back into")]
        [SecurityCritical] 
        SecurityContext context;
        bool isScheduled; 
 
        bool lowPriority;
 
        protected ActionItem()
        {
        }
 
        public bool LowPriority
        { 
            get 
            {
                return this.lowPriority; 
            }
            protected set
            {
                this.lowPriority = value; 
            }
        } 
 
        public static void Schedule(Action callback, object state)
        { 
            Schedule(callback, state, false);
        }
        [Fx.Tag.SecurityNote(Critical = "Calls into critical method ScheduleCallback",
            Safe = "Schedule invoke of the given delegate under the current context")] 
        [SecuritySafeCritical]
        public static void Schedule(Action callback, object state, bool lowPriority) 
        { 
            Fx.Assert(callback != null, "A null callback was passed for Schedule!");
 
            if (PartialTrustHelpers.ShouldFlowSecurityContext || WaitCallbackActionItem.ShouldUseActivity)
            {
                new DefaultActionItem(callback, state, lowPriority).Schedule();
            } 
            else
            { 
                ScheduleCallback(callback, state, lowPriority); 
            }
        } 

        [Fx.Tag.SecurityNote(Critical = "Called after applying the user context on the stack or (potentially) " +
            "without any user context on the stack")]
        [SecurityCritical] 
        protected abstract void Invoke();
 
        [Fx.Tag.SecurityNote(Critical = "Access critical field context and critical property " + 
            "CallbackHelper.InvokeWithContextCallback, calls into critical method " +
            "PartialTrustHelpers.CaptureSecurityContextNoIdentityFlow, calls into critical method ScheduleCallback; " + 
            "since the invoked method and the capturing of the security contex are de-coupled, can't " +
            "be treated as safe")]
        [SecurityCritical]
        protected void Schedule() 
        {
            if (isScheduled) 
            { 
                throw Fx.Exception.AsError(new InvalidOperationException(SRCore.ActionItemIsAlreadyScheduled));
            } 

            this.isScheduled = true;
            if (PartialTrustHelpers.ShouldFlowSecurityContext)
            { 
                this.context = PartialTrustHelpers.CaptureSecurityContextNoIdentityFlow();
            } 
            if (this.context != null) 
            {
                ScheduleCallback(CallbackHelper.InvokeWithContextCallback); 
            }
            else
            {
                ScheduleCallback(CallbackHelper.InvokeWithoutContextCallback); 
            }
        } 
        [Fx.Tag.SecurityNote(Critical = "Access critical field context and critical property " + 
            "CallbackHelper.InvokeWithContextCallback, calls into critical method ScheduleCallback; " +
            "since nothing is known about the given context, can't be treated as safe")] 
        [SecurityCritical]
        protected void ScheduleWithContext(SecurityContext context)
        {
            if (context == null) 
            {
                throw Fx.Exception.ArgumentNull("context"); 
            } 
            if (isScheduled)
            { 
                throw Fx.Exception.AsError(new InvalidOperationException(SRCore.ActionItemIsAlreadyScheduled));
            }

            this.isScheduled = true; 
            this.context = context.CreateCopy();
            ScheduleCallback(CallbackHelper.InvokeWithContextCallback); 
        } 
        [Fx.Tag.SecurityNote(Critical = "Access critical property CallbackHelper.InvokeWithoutContextCallback, " +
            "Calls into critical method ScheduleCallback; not bound to a security context")] 
        [SecurityCritical]
        protected void ScheduleWithoutContext()
        {
            if (isScheduled) 
            {
                throw Fx.Exception.AsError(new InvalidOperationException(SRCore.ActionItemIsAlreadyScheduled)); 
            } 

            this.isScheduled = true; 
            ScheduleCallback(CallbackHelper.InvokeWithoutContextCallback);
        }

        [Fx.Tag.SecurityNote(Critical = "Calls into critical methods IOThreadScheduler.ScheduleCallbackNoFlow, " + 
            "IOThreadScheduler.ScheduleCallbackLowPriNoFlow")]
        [SecurityCritical] 
        static void ScheduleCallback(Action callback, object state, bool lowPriority) 
        {
            Fx.Assert(callback != null, "Cannot schedule a null callback"); 
            if (lowPriority)
            {
                IOThreadScheduler.ScheduleCallbackLowPriNoFlow(callback, state);
            } 
            else
            { 
                IOThreadScheduler.ScheduleCallbackNoFlow(callback, state); 
            }
        } 

        [Fx.Tag.SecurityNote(Critical = "Extract the security context stored and reset the critical field")]
        [SecurityCritical]
        SecurityContext ExtractContext() 
        {
            Fx.Assert(this.context != null, "Cannot bind to a null context; context should have been set by now"); 
            Fx.Assert(this.isScheduled, "Context is extracted only while the object is scheduled"); 
            SecurityContext result = this.context;
            this.context = null; 
            return result;
        }

        [Fx.Tag.SecurityNote(Critical = "Calls into critical static method ScheduleCallback")] 
        [SecurityCritical]
        void ScheduleCallback(Action callback) 
        { 
            ScheduleCallback(callback, this, this.lowPriority);
        } 

        [SecurityCritical]
        static class CallbackHelper
        { 
            [Fx.Tag.SecurityNote(Critical = "Stores a delegate to a critical method")]
            static Action invokeWithContextCallback; 
            [Fx.Tag.SecurityNote(Critical = "Stores a delegate to a critical method")] 
            static Action invokeWithoutContextCallback;
            [Fx.Tag.SecurityNote(Critical = "Stores a delegate to a critical method")] 
            static ContextCallback onContextAppliedCallback;
            [Fx.Tag.SecurityNote(Critical = "Provides access to a critical field; Initialize it with " +
                "a delegate to a critical method")]
            public static Action InvokeWithContextCallback 
            {
                get 
                { 
                    if (invokeWithContextCallback == null)
                    { 
                        invokeWithContextCallback = new Action(InvokeWithContext);
                    }
                    return invokeWithContextCallback;
                } 
            }
 
            [Fx.Tag.SecurityNote(Critical = "Provides access to a critical field; Initialize it with " + 
                "a delegate to a critical method")]
            public static Action InvokeWithoutContextCallback 
            {
                get
                {
                    if (invokeWithoutContextCallback == null) 
                    {
                        invokeWithoutContextCallback = new Action(InvokeWithoutContext); 
                    } 
                    return invokeWithoutContextCallback;
                } 
            }
            [Fx.Tag.SecurityNote(Critical = "Provides access to a critical field; Initialize it with " +
                "a delegate to a critical method")]
            public static ContextCallback OnContextAppliedCallback 
            {
                get 
                { 
                    if (onContextAppliedCallback == null)
                    { 
                        onContextAppliedCallback = new ContextCallback(OnContextApplied);
                    }
                    return onContextAppliedCallback;
                } 
            }
            [Fx.Tag.SecurityNote(Critical = "Called by the scheduler without any user context on the stack")] 
            static void InvokeWithContext(object state) 
            {
                SecurityContext context = ((ActionItem)state).ExtractContext(); 
                SecurityContext.Run(context, OnContextAppliedCallback, state);
            }

            [Fx.Tag.SecurityNote(Critical = "Called by the scheduler without any user context on the stack")] 
            static void InvokeWithoutContext(object state)
            { 
                ((ActionItem)state).Invoke(); 
                ((ActionItem)state).isScheduled = false;
            } 
            [Fx.Tag.SecurityNote(Critical = "Called after applying the user context on the stack")]
            static void OnContextApplied(object o)
            {
                ((ActionItem)o).Invoke(); 
                ((ActionItem)o).isScheduled = false;
            } 
        } 

        class DefaultActionItem : ActionItem 
        {
            [Fx.Tag.SecurityNote(Critical = "Stores a delegate that will be called later, at a particular context")]
            [SecurityCritical]
            Action callback; 
            [Fx.Tag.SecurityNote(Critical = "Stores an object that will be passed to the delegate that will be " +
                "called later, at a particular context")] 
            [SecurityCritical] 
            object state;
 
            bool flowActivityId;
            Guid activityId;

            [Fx.Tag.SecurityNote(Critical = "Access critical fields callback and state", 
                Safe = "Doesn't leak information or resources")]
            [SecuritySafeCritical] 
            public DefaultActionItem(Action callback, object state, bool isLowPriority) 
            {
                Fx.Assert(callback != null, "Shouldn't instantiate an object to wrap a null callback"); 
                base.LowPriority = isLowPriority;
                this.callback = callback;
                this.state = state;
                if (WaitCallbackActionItem.ShouldUseActivity) 
                {
                    this.flowActivityId = true; 
                    this.activityId = DiagnosticTrace.ActivityId; 
                }
            } 

            [Fx.Tag.SecurityNote(Critical = "Implements a the critical abstract ActionItem.Invoke method, " +
                "Access critical fields callback and state")]
            [SecurityCritical] 
            protected override void Invoke()
            { 
                if (this.flowActivityId) 
                {
                    Guid currentActivityId = DiagnosticTrace.ActivityId; 
                    try
                    {
                        DiagnosticTrace.ActivityId = this.activityId;
                        this.callback(this.state); 
                    }
                    finally 
                    { 
                        DiagnosticTrace.ActivityId = currentActivityId;
                    } 
                }
                else
                {
                    this.callback(this.state); 
                }
            } 
        } 
    }
} 

// 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