Synchronization.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / TransactionBridge / Microsoft / Transactions / Wsat / StateMachines / Synchronization.cs / 2 / Synchronization.cs

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

// This file contains a simple implementation of a non-blocking queue that 
// provides the synchronized delivery of events
 
using System; 

using System.ServiceModel.Channels; 
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Threading; 

using Microsoft.Transactions.Bridge; 
using Microsoft.Transactions.Wsat.Messaging; 
using Microsoft.Transactions.Wsat.Protocol;
 
namespace Microsoft.Transactions.Wsat.StateMachines
{
    class SynchronizationManager
    { 
        Queue queue = new Queue();
        object mutex = new object(); 
 
        StateMachine stateMachine;
 
        public SynchronizationManager (StateMachine stateMachine)
        {
            this.stateMachine = stateMachine;
        } 

        public void Enqueue (SynchronizationEvent newEvent) 
        { 
            if (newEvent == null)
            { 
                // An attempt to Enqueue a null is a bug and will cause
                // an unstable extension.
                DiagnosticUtility.FailFast("The synchronization manager cannot enqueue a null event");
            } 

            // Always trace a transfer event from the current E2E activity id to 
            // the state machine's enlistment id. This allows us to correlate activities 
            // in client processes that send us messages to our own enlistment ids
            // 
            // Note: the assumption here is that ServiceModel is setting the current activity id
            // prior to dispatch.
            if (DiagnosticUtility.ShouldUseActivity)
            { 
                DiagnosticUtility.DiagnosticTrace.TraceTransfer(this.stateMachine.Enlistment.EnlistmentId);
            } 
 
            bool weOwnTheQueue;
            lock (this.mutex) 
            {
                this.queue.Enqueue (newEvent);
                weOwnTheQueue = (this.queue.Count == 1);
            } 

            if (weOwnTheQueue) 
            { 
                Execute();
            } 
        }

        void Execute()
        { 
            if (DebugTrace.Verbose)
            { 
                DebugTrace.TxTrace( 
                    TraceLevel.Verbose,
                    this.stateMachine.Enlistment.EnlistmentId, 
                    "Now processing events on {0}",
                    this.stateMachine.GetType().Name
                    );
            } 

            while (true) 
            { 
                SynchronizationEvent newEvent = this.queue.Peek();
                if (newEvent == null) 
                {
                    // Somehow, a null event was Enqueued. This means that something
                    // is unstable and we need to close.
                    DiagnosticUtility.FailFast("Peek returned null synchronization event"); 
                }
 
                try 
                {
                    if (DebugTrace.Verbose) 
                    {
                        DebugTrace.TxTrace(
                            TraceLevel.Verbose,
                            this.stateMachine.Enlistment.EnlistmentId, 
                            "Dispatching {0} event to {1} in {2}",
                            newEvent.GetType().Name, 
                            this.stateMachine.GetType().Name, 
                            this.stateMachine.State.GetType().Name
                            ); 
                    }

                    // Always wrap the event dispatch in the enlistment's activity id
                    // This ensures that traces generated by 3rd parties during dispatch 
                    // are correlated to our enlistment id
                    using (System.ServiceModel.Diagnostics.Activity.CreateActivity(this.stateMachine.Enlistment.EnlistmentId)) 
                    { 
                        // Dispatch the event to the enlistment's state machine
                        this.stateMachine.Dispatch(newEvent); 
                    }

                    if (DebugTrace.Verbose)
                    { 
                        DebugTrace.TxTrace(
                            TraceLevel.Verbose, 
                            this.stateMachine.Enlistment.EnlistmentId, 
                            "Dispatched {0} event to {1} in {2}",
                            newEvent.GetType().Name, 
                            this.stateMachine.GetType().Name,
                            this.stateMachine.State.GetType().Name
                            );
                    } 
                }
#pragma warning suppress 56500 // Only catch Exception for InvokeFinalHandler 
                catch (Exception e) 
                {
                    // This is a really bad error 
                    DebugTrace.TxTrace(
                        TraceLevel.Error,
                        this.stateMachine.Enlistment.EnlistmentId,
                        "REALLY BAD ERROR: Unhandled exception caught by synchronization manager: {0}", e 
                        );
 
                    UnhandledStateMachineExceptionRecord.TraceAndLog( 
                        this.stateMachine.Enlistment.EnlistmentId,
                        (this.stateMachine.Enlistment.Enlistment != null) ? this.stateMachine.Enlistment.Enlistment.RemoteTransactionId : string.Empty, 
                        this.stateMachine.ToString(),
                        this.stateMachine.State.ToString(),
                        this.stateMachine.History,
                        e 
                        );
 
                    string text = string.Format(CultureInfo.InvariantCulture, 
                                                "Failfasting due to unhandled exception: {0}\r\n\r\n{1}",
                                                e.Message, e); 

                    // A state machine cannot fail or throw an exception while processing an event
                    // This indicates that things have gone seriously wrong,
                    // so we cannot be trusted to perform any further processing. 
                    // This is a QFE-worthy event.
                    DiagnosticUtility.FailFast(text); 
                } 

                lock (this.mutex) 
                {
                    this.queue.Dequeue();
                    if (this.queue.Count == 0)
                    { 
                        break;
                    } 
                } 

                if (DebugTrace.Verbose) 
                {
                    DebugTrace.TxTrace(
                        TraceLevel.Verbose,
                        this.stateMachine.Enlistment.EnlistmentId, 
                        "Continuing to process events on {0}",
                        this.stateMachine.GetType().Name 
                        ); 
                }
            } 

            if (DebugTrace.Verbose)
            {
                DebugTrace.TxTrace( 
                    TraceLevel.Verbose,
                    this.stateMachine.Enlistment.EnlistmentId, 
                    "Stopped processing events on {0}", 
                    this.stateMachine.GetType().Name
                    ); 
            }
        }
    }
} 

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

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