static BodyDelegate WrapBodyDelegate(ExecutionContext context, BodyDelegate body)
 {
     return body == null ? (BodyDelegate)null : (write, flush, end, cancellationToken) => ExecutionContext.Run(
         context.CreateCopy(),
         _ => body(write, WrapFlushDelegate(context, flush), end, cancellationToken),
         null);
 }
        static Func<ArraySegment<byte>, Action<Exception>, TempEnum> WrapWriteDelegate(ExecutionContext context, Func<ArraySegment<byte>, Action<Exception>, TempEnum> write)
        {
            return (data, callback) =>
            {
                if (callback == null)
                {
                    return write(data, null);
                }

                return write(data, ex => ExecutionContext.Run(context.CreateCopy(), state => callback((Exception)state), ex));
            };
        }
        static BodyDelegate WrapBodyDelegate(ExecutionContext context, BodyDelegate body)
        {
            if (body == null)
            {
                return null;
            }

            return (write, end, cancellationToken) => ExecutionContext.Run(
                context.CreateCopy(),
                _ => body(WrapWriteDelegate(context, write), end, cancellationToken),
                null);
        }
        internal static void RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, bool preserveSyncCtx)
        {
            Contract.Assert(executionContext != null);
            if (executionContext.IsPreAllocatedDefault)
            {
                Contract.Assert(executionContext.IsDefaultFTContext(preserveSyncCtx));
            }
            else
            {
                Contract.Assert(executionContext.isNewCapture);
                executionContext.isNewCapture = false;
            }

            Thread currentThread          = Thread.CurrentThread;
            ExecutionContextSwitcher ecsw = default(ExecutionContextSwitcher);

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                ExecutionContext.Reader ec = currentThread.GetExecutionContextReader();
                if ((ec.IsNull || ec.IsDefaultFTContext(preserveSyncCtx)) &&
    #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
                    SecurityContext.CurrentlyInDefaultFTSecurityContext(ec) &&
    #endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
                    executionContext.IsDefaultFTContext(preserveSyncCtx))
                {
                    // Neither context is interesting, so we don't need to set the context.
                    // We do need to reset any changes made by the user's callback,
                    // so here we establish a "copy-on-write scope".  Any changes will
                    // result in a copy of the context being made, preserving the original
                    // context.
                    EstablishCopyOnWriteScope(currentThread, true, ref ecsw);
                }
                else
                {
                    if (executionContext.IsPreAllocatedDefault)
                    {
                        executionContext = executionContext.CreateCopy();
                    }
                    ecsw = SetExecutionContext(executionContext, preserveSyncCtx);
                }

                //
                // Call the user's callback
                //
                callback(state);
            }
            finally
            {
                ecsw.Undo(currentThread);
            }
        }
Beispiel #5
0
        private void FinishPhase(bool observedSense)
        {
            // Execute the PHA in try/finally block to reset the variables back in case of it threw an exception
            if (m_postPhaseAction != null)
            {
                try
                {
                    // Capture the caller thread ID to check if the Add/RemoveParticipant(s) is called from the PHA
                    m_actionCallerID = Thread.CurrentThread.ManagedThreadId;
                    if (m_ownerThreadContext != null)
                    {
                        var currentContext = m_ownerThreadContext;
                        m_ownerThreadContext = m_ownerThreadContext.CreateCopy(); // create a copy for the next run

                        ContextCallback handler = s_invokePostPhaseAction;
                        if (handler == null)
                        {
                            s_invokePostPhaseAction = handler = InvokePostPhaseAction;
                        }
                        ExecutionContext.Run(currentContext, handler, this);
#if !PFX_LEGACY_3_5
                        // Dispose the context directly after using it,
                        // the copy will either be used and siposed in the next phase or in the Dispose
                        currentContext.Dispose();
#endif
                    }
                    else
                    {
                        m_postPhaseAction(this);
                    }
                    m_exception = null; // reset the exception if it was set previously
                }
                catch (Exception ex)
                {
                    m_exception = ex;
                }
                finally
                {
                    m_actionCallerID = 0;
                    SetResetEvents(observedSense);
                    if (m_exception != null)
                    {
                        throw new BarrierPostPhaseException(m_exception);
                    }
                }
            }
            else
            {
                SetResetEvents(observedSense);
            }
        }
Beispiel #6
0
        private void FinishPhase(bool observedSense)
        {
            // Execute the PHA in try/finally block to reset the variables back in case of it threw an exception
            if (_postPhaseAction != null)
            {
                try
                {
                    // Capture the caller thread ID to check if the Add/RemoveParticipant(s) is called from the PHA
                    _actionCallerId = Thread.CurrentThread.ManagedThreadId;
                    if (_ownerThreadContext != null)
                    {
                        var currentContext = _ownerThreadContext;
                        _ownerThreadContext = _ownerThreadContext.CreateCopy(); // create a copy for the next run

                        var handler = _invokePostPhaseAction;
                        if (handler == null)
                        {
                            _invokePostPhaseAction = handler = InvokePostPhaseAction;
                        }
                        ExecutionContext.Run(currentContext, handler, this);
                    }
                    else
                    {
                        _postPhaseAction(this);
                    }
                    _exception = null; // reset the exception if it was set previously
                }
                catch (Exception ex)
                {
                    _exception = ex;
                }
                finally
                {
                    _actionCallerId = 0;
                    SetResetEvents(observedSense);
                    if (_exception != null)
                    {
                        throw new BarrierPostPhaseException(_exception);
                    }
                }
            }
            else
            {
                SetResetEvents(observedSense);
            }
        }
Beispiel #7
0
 /// <summary>
 /// Finish the phase by invoking the post phase action, and setting the event, this must be called by the
 /// last arrival thread
 /// </summary>
 /// <param name="observedSense">The current phase sense</param>
 private void FinishPhase(bool observedSense)
 {
     // Execute the PHA in try/finally block to reset the variables back in case of it threw an exception
     if (m_postPhaseAction != null)
     {
         try
         {
             // Capture the caller thread ID to check if the Add/RemoveParticipant(s) is called from the PHA
             m_actionCallerID = Thread.CurrentThread.ManagedThreadId;
             if (m_ownerThreadContext != null)
             {
                 ExecutionContext.Run(m_ownerThreadContext.CreateCopy(), i => m_postPhaseAction(this), null);
             }
             else
             {
                 m_postPhaseAction(this);
             }
             m_exception = null; // reset the exception if it was set previously
         }
         catch (Exception ex)
         {
             m_exception = ex;
         }
         finally
         {
             m_actionCallerID = 0;
             SetResetEvents(observedSense);
             if (m_exception != null)
             {
                 throw new BarrierPostPhaseException(m_exception);
             }
         }
     }
     else
     {
         SetResetEvents(observedSense);
     }
 }
 private bool CaptureOrComplete(ref ExecutionContext cachedContext, bool returnContext)
 {
     bool flag = (base.AsyncCallback != null) || ((this._Flags & StateFlags.CaptureContext) != StateFlags.None);
     if ((((this._Flags & StateFlags.CaptureIdentity) != StateFlags.None) && !base.InternalPeekCompleted) && (!flag || SecurityContext.IsWindowsIdentityFlowSuppressed()))
     {
         this.SafeCaptureIdenity();
     }
     if (flag && !base.InternalPeekCompleted)
     {
         if (cachedContext == null)
         {
             cachedContext = ExecutionContext.Capture();
         }
         if (cachedContext != null)
         {
             if (!returnContext)
             {
                 this._Context = cachedContext;
                 cachedContext = null;
             }
             else
             {
                 this._Context = cachedContext.CreateCopy();
             }
         }
     }
     else
     {
         cachedContext = null;
     }
     if (base.CompletedSynchronously)
     {
         base.Complete(IntPtr.Zero);
         return true;
     }
     return false;
 }
Beispiel #9
0
        internal void CallCallback()
        {
            if (FrameworkEventSource.IsInitialized && FrameworkEventSource.Log.IsEnabled(EventLevel.Informational, FrameworkEventSource.Keywords.ThreadTransfer))
            {
                FrameworkEventSource.Log.ThreadTransferReceiveObj(this, 1, string.Empty);
            }

            // call directly if EC flow is suppressed
            if (m_executionContext == null)
            {
                m_timerCallback(m_state);
            }
            else
            {
                using (ExecutionContext executionContext =
                           m_executionContext.IsPreAllocatedDefault ? m_executionContext : m_executionContext.CreateCopy())
                {
                    ContextCallback callback = s_callCallbackInContext;
                    if (callback == null)
                    {
                        s_callCallbackInContext = callback = new ContextCallback(CallCallbackInContext);
                    }

                    ExecutionContext.Run(
                        executionContext,
                        callback,
                        this,  // state
                        true); // ignoreSyncCtx
                }
            }
        }
Beispiel #10
0
        internal void CallCallback()
        {
            // call directly if EC flow is suppressed
            if (m_executionContext == null)
            {
                m_timerCallback(m_state);
            }
            else
            {
                using (ExecutionContext executionContext =
                           m_executionContext.IsPreAllocatedDefault ? m_executionContext : m_executionContext.CreateCopy())
                {
                    ContextCallback callback = s_callCallbackInContext;
                    if (callback == null)
                    {
                        s_callCallbackInContext = callback = new ContextCallback(CallCallbackInContext);
                    }

                    ExecutionContext.Run(
                        executionContext,
                        callback,
                        this,  // state
                        true); // ignoreSyncCtx
                }
            }
        }
        internal static void RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, bool preserveSyncCtx)
        {
            Contract.Assert(executionContext != null);
            if (executionContext.IsPreAllocatedDefault)
            {
                Contract.Assert(executionContext.IsDefaultFTContext(preserveSyncCtx));
            }
            else
            {
                Contract.Assert(executionContext.isNewCapture);
                executionContext.isNewCapture = false;
            }

            Thread currentThread = Thread.CurrentThread;
            ExecutionContextSwitcher ecsw = default(ExecutionContextSwitcher);

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                ExecutionContext.Reader ec = currentThread.GetExecutionContextReader();
                if ( (ec.IsNull || ec.IsDefaultFTContext(preserveSyncCtx)) && 
    #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK                
                    SecurityContext.CurrentlyInDefaultFTSecurityContext(ec) && 
    #endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK                
                    executionContext.IsDefaultFTContext(preserveSyncCtx))
                {
                    // Neither context is interesting, so we don't need to set the context.
                    // We do need to reset any changes made by the user's callback,
                    // so here we establish a "copy-on-write scope".  Any changes will
                    // result in a copy of the context being made, preserving the original
                    // context.
                    EstablishCopyOnWriteScope(currentThread, true, ref ecsw);
                }
                else
                {
                    if (executionContext.IsPreAllocatedDefault)
                        executionContext = executionContext.CreateCopy();
                    ecsw = SetExecutionContext(executionContext, preserveSyncCtx);
                }

                //
                // Call the user's callback
                //
                callback(state);
            }
            finally
            {
                ecsw.Undo(currentThread);
            }
        }
Beispiel #12
0
        // This must be called right before returning the result to the user.  It might call the callback itself,
        // to avoid flowing context.  Even if the operation completes before this call, the callback won't have been
        // called.
        //
        // Returns whether the operation completed sync or not.
        private bool CaptureOrComplete(ref ExecutionContext cachedContext, bool returnContext)
        {
            GlobalLog.Assert((_flags & StateFlags.PostBlockStarted) != 0, "ContextAwareResult#{0}::CaptureOrComplete|Called without calling StartPostingAsyncOp.", Logging.HashString(this));

            // See if we're going to need to capture the context.
            bool capturingContext = AsyncCallback != null || (_flags & StateFlags.CaptureContext) != 0;

            // Peek if we've already completed, but don't fix CompletedSynchronously yet
            // Capture the identity if requested, unless we're going to capture the context anyway, unless
            // capturing the context won't be sufficient.
            if ((_flags & StateFlags.CaptureIdentity) != 0 && !InternalPeekCompleted && (!capturingContext))
            {
                GlobalLog.Print("ContextAwareResult#" + Logging.HashString(this) + "::CaptureOrComplete() starting identity capture");
                SafeCaptureIdentity();
            }

            // No need to flow if there's no callback, unless it's been specifically requested.
            // Note that Capture() can return null, for example if SuppressFlow() is in effect.
            if (capturingContext && !InternalPeekCompleted)
            {
                GlobalLog.Print("ContextAwareResult#" + Logging.HashString(this) + "::CaptureOrComplete() starting capture");
                if (cachedContext == null)
                {
                    cachedContext = ExecutionContext.Capture();
                }

                if (cachedContext != null)
                {
                    if (!returnContext)
                    {
                        _context = cachedContext;
                        cachedContext = null;
                    }
                    else
                    {
                        _context = cachedContext.CreateCopy();
                    }
                }
                GlobalLog.Print("ContextAwareResult#" + Logging.HashString(this) + "::CaptureOrComplete() _Context:" + Logging.HashString(_context));
            }
            else
            {
                // Otherwise we have to have completed synchronously, or not needed the context.
                GlobalLog.Print("ContextAwareResult#" + Logging.HashString(this) + "::CaptureOrComplete() skipping capture");
                cachedContext = null;
                GlobalLog.Assert(AsyncCallback == null || CompletedSynchronously, "ContextAwareResult#{0}::CaptureOrComplete|Didn't capture context, but didn't complete synchronously!", Logging.HashString(this));
            }

            // Now we want to see for sure what to do.  We might have just captured the context for no reason.
            // This has to be the first time the state has been queried "for real" (apart from InvokeCallback)
            // to guarantee synchronization with Complete() (otherwise, Complete() could try to call the
            // callback without the context having been gotten).
            DebugProtectState(false);
            if (CompletedSynchronously)
            {
                GlobalLog.Print("ContextAwareResult#" + Logging.HashString(this) + "::CaptureOrComplete() completing synchronously");
                base.Complete(IntPtr.Zero);
                return true;
            }

            return false;
        }
 static Func<Action, bool> WrapFlushDelegate(ExecutionContext context, Func<Action, bool> flush)
 {
     return drained => drained == null ? flush(null) : flush(() => ExecutionContext.Run(context.CreateCopy(), _ => drained(), null));
 }
 static Func<ArraySegment<byte>, Action, bool> WrapWriteDelegate(ExecutionContext context, Func<ArraySegment<byte>, Action, bool> write)
 {
     return (data, callback) => callback == null ? write(data, null) : write(data, () => ExecutionContext.Run(context.CreateCopy(), _ => callback(), null));
 }