public TransactionContext(WorkflowServiceInstance durableInstance, Transaction currentTransaction)
        {
            Fx.Assert(durableInstance != null, "Null DurableInstance passed to TransactionContext.");
            Fx.Assert(currentTransaction != null, "Null Transaction passed to TransactionContext.");

            this.currentTransaction = currentTransaction.Clone();
            this.durableInstance = durableInstance;
            this.currentTransaction.EnlistVolatile(this, EnlistmentOptions.EnlistDuringPrepareRequired);
        }
 private WorkflowOperationContext(object[] inputs, System.ServiceModel.OperationContext operationContext, string operationName, bool performanceCountersEnabled, bool propagateActivity, Transaction currentTransaction, WorkflowServiceInstance workflowInstance, IInvokeReceivedNotification notification, WorkflowOperationBehavior behavior, TimeSpan timeout, AsyncCallback callback, object state) : base(callback, state)
 {
     this.inputs = inputs;
     this.operationName = operationName;
     this.OperationContext = operationContext;
     this.CurrentTransaction = currentTransaction;
     this.performanceCountersEnabled = performanceCountersEnabled;
     this.propagateActivity = propagateActivity;
     this.timeoutHelper = new TimeoutHelper(timeout);
     this.workflowInstance = workflowInstance;
     this.thisLock = new object();
     this.notification = notification;
     base.OnCompleting = onCompleting;
     this.bookmark = behavior.OnResolveBookmark(this, out this.bookmarkScope, out this.bookmarkValue);
     bool flag = false;
     try
     {
         if (TraceUtility.MessageFlowTracingOnly)
         {
             this.e2eActivityId = TraceUtility.GetReceivedActivityId(this.OperationContext);
             DiagnosticTrace.ActivityId = this.e2eActivityId;
         }
         if (this.workflowInstance.BufferedReceiveManager != null)
         {
             ReceiveContext.TryGet(this.OperationContext.IncomingMessageProperties, out this.receiveContext);
             this.OperationContext.IncomingMessageProperties.Remove(ReceiveContext.Name);
         }
         flag = this.ProcessRequest();
     }
     catch (Exception exception)
     {
         if (Fx.IsFatal(exception))
         {
             throw;
         }
         base.OnCompleting(this, exception);
         throw;
     }
     if (flag)
     {
         base.Complete(true);
     }
 }
 protected virtual object OnEndServiceOperation(WorkflowServiceInstance durableInstance, out object[] outputs, IAsyncResult result)
 {
     return ServiceOperationAsyncResult.End(out outputs, result);
 }
 bool RunInstance()
 {
     try
     {
         IAsyncResult result = this.currentInstance.BeginRun(null, TimeSpan.MaxValue, PrepareAsyncCompletion(handleEndRunInstance), this);
         return SyncContinue(result);
     }
     catch (Exception exception)
     {
         if (Fx.IsFatal(exception))
         {
             throw;
         }
         if (this.currentInstance != null)
         {
             this.currentInstance.ReleaseReference();
             this.currentInstance = null;
         }
         if (!this.instanceManager.HandleException(exception))
         {
             throw;
         }
     }
     return HandleStoreEvents();
 }
            bool TryAcquire(bool fromCache)
            {
                this.durableInstance = this.persistenceContext.GetInstance(this.parameters);

                if (!fromCache)
                {
                    this.referenceAcquired = true;
                    return AssociateKeys();
                }

                IAsyncResult nextResult = this.durableInstance.BeginTryAcquireReference(this.timeout, this.PrepareAsyncCompletion(handleEndAcquireReference), this);
                return SyncContinue(nextResult);
            }
                public UnlockAndAbortAsyncResult(WorkflowServiceInstance instance, TimeSpan timeout, AsyncCallback callback, object state)
                    : base(callback, state)
                {
                    this.instance = instance;
                    this.timeoutHelper = new TimeoutHelper(timeout);
                    this.OnCompleting = onCompleting;

                    Exception completionException = null;
                    bool completeSelf = true;

                    if (this.instance.acquireReferenceSemaphore.EnterAsync(this.timeoutHelper.RemainingTime(), acquireCompletedCallback, this))
                    {
                        try
                        {
                            completeSelf = this.HandleEndAcquireReference();
                        }
                        catch (Exception exception)
                        {
                            if (Fx.IsFatal(exception))
                            {
                                throw;
                            }
                            completionException = exception;
                        }
                    }
                    else
                    {
                        completeSelf = false;
                    }

                    if (completeSelf)
                    {
                        Complete(true, completionException);
                    }
                }
            public WorkflowPersistenceContext(WorkflowServiceInstance instance, bool transactionRequired, Transaction transactionToUse, TimeSpan transactionTimeout)
            {
                this.instance = instance;

                if (transactionToUse != null)
                {
                    this.clonedTransaction = transactionToUse;
                }
                else if (transactionRequired)
                {
                    this.contextOwnedTransaction = new CommittableTransaction(transactionTimeout);
                    // Clone it so that we don't pass a CommittableTransaction to the participants
                    this.clonedTransaction = this.contextOwnedTransaction.Clone();
                }
            }
 public WorkflowExecutionLock(WorkflowServiceInstance instance)
 {
     this.instance = instance;
 }
 AbandonAndSuspendAsyncResult(WorkflowServiceInstance instance, Exception reason, AsyncCallback callback, object state)
     : base(instance, null, callback, state)
 {
     this.reason = reason;
 }
 public static AbandonAsyncResult Create(WorkflowServiceInstance instance, Exception reason, bool shouldTrackAbort, TimeSpan timeout, AsyncCallback callback, object state)
 {
     AbandonAsyncResult result = new AbandonAsyncResult(instance, reason, shouldTrackAbort, callback, state);
     result.Run(timeout);
     return result;
 }
 AbandonAsyncResult(WorkflowServiceInstance instance, Exception reason, bool shouldTrackAbort, AsyncCallback callback, object state)
     : base(instance, null, callback, state)
 {
     this.reason = reason;
     this.shouldTrackAbort = shouldTrackAbort;
 }
 public static TerminateAsyncResult Create(WorkflowServiceInstance instance, Exception reason, Transaction transaction, TimeSpan timeout, AsyncCallback callback, object state)
 {
     TerminateAsyncResult result = new TerminateAsyncResult(instance, reason, transaction, callback, state);
     result.Run(timeout);
     return result;
 }
 TerminateAsyncResult(WorkflowServiceInstance instance, Exception reason, Transaction transaction, AsyncCallback callback, object state)
     : base(instance, transaction, callback, state)
 {
     this.reason = reason;
 }
 protected SimpleOperationAsyncResult(WorkflowServiceInstance instance, Transaction transaction, AsyncCallback callback, object state)
     : base(callback, state)
 {
     this.instance = instance;
     this.OperationTransaction = transaction;
     this.OnCompleting = onCompleting;
 }
            public UnloadOrPersistAsyncResult(WorkflowServiceInstance instance, PersistenceOperation operation,
                bool isWorkflowThread, bool isTry, TimeSpan timeout, AsyncCallback callback, object state)
                : base(callback, state)
            {
                // The isTry flag is only true when this is an idle policy initiated persist/unload.
                
                Fx.Assert((isWorkflowThread && !isTry) || !isWorkflowThread, "Either we're the workflow thread and NOT a try or we're not a workflow thread.");

                this.instance = instance;
                this.timeoutHelper = new TimeoutHelper(timeout);
                this.operation = operation;
                this.isWorkflowThread = isWorkflowThread;
                this.isTry = isTry;
                this.tryResult = true;
                this.isUnloaded = (operation == PersistenceOperation.Unload || operation == PersistenceOperation.Delete);
                this.saveStatus = SaveStatus.Locked;
                this.isCompletionTransactionRequired = this.isUnloaded && instance.Controller.State == WorkflowInstanceState.Complete && 
                    instance.creationContext != null && instance.creationContext.IsCompletionTransactionRequired;
                this.isIdlePolicyPersist = isTry && operation == PersistenceOperation.Save;

                if (operation == PersistenceOperation.Unload)
                {
                    this.saveStatus = SaveStatus.Unlocked;
                }
                else if (operation == PersistenceOperation.Delete)
                {
                    this.saveStatus = SaveStatus.Completed;
                }
                else if (operation == PersistenceOperation.Save)
                {
                    SetStartTime();
                }
                
                // Save off the current transaction in case we have an async operation before we end up creating
                // the WorkflowPersistenceContext and create it on another thread. Do a simple clone here to prevent
                // the object referenced by Transaction.Current from disposing before we get around to referencing it
                // when we create the WorkflowPersistenceContext.
                //
                // This will throw TransactionAbortedException by design, if the transaction is already rolled back.
                Transaction currentTransaction = Transaction.Current;
                if (currentTransaction != null)
                {
                    OnCompleting = UnloadOrPersistAsyncResult.completeCallback;
                    this.dependentTransaction = currentTransaction.DependentClone(DependentCloneOption.BlockCommitUntilComplete);
                }

                bool completeSelf = true;
                bool success = false;
                try
                {
                    if (this.isWorkflowThread)
                    {
                        Fx.Assert(this.instance.Controller.IsPersistable, "The runtime won't schedule this work item unless we've passed the guard");

                        // We're an internal persistence on the workflow thread which means
                        // that we are passed the guard already, we have the lock, and we know
                        // we aren't detached.

                        completeSelf = OpenProvider();
                    }
                    else
                    {
                        try
                        {
                            completeSelf = LockAndPassGuard();
                        }
                        finally
                        {
                            if (completeSelf)
                            {
                                Fx.Assert(!this.isWorkflowThread, "We should never be calling ReleaseLock if this is the workflow thread.");

                                this.instance.ReleaseLock(ref this.ownsLock, this.isIdlePolicyPersist && this.tryResult);
                            }
                        }
                    }
                    success = true;
                }
                finally
                {
                    if (!success)
                    {
                        if (this.dependentTransaction != null)
                        {
                            this.dependentTransaction.Complete();
                        }
                    }
                }

                if (completeSelf)
                {
                    Complete(true);
                }
            }
            public AcquireLockOnIdleAsyncResult(WorkflowServiceInstance instance, TimeSpan timeout, ref bool ownsLock, AsyncCallback callback, object state)
                : base(callback, state)
            {
                Fx.Assert(!ownsLock, "We should never call acquire if we already think we own the lock.");

                // We cannot just hand off the lock if we are in a handler thread
                // because this might eventually go async (during the operation)
                // and we could have multiple operations occurring concurrently.

                this.instance = instance;
                this.timeoutHelper = new TimeoutHelper(timeout);

                bool incrementedActiveOperations = false;
                bool decrementActiveOperations = true;
                bool completeSelf = true;
                object lockToken = null;

                try
                {
                    lock (this.instance.activeOperationsLock)
                    {
                        try
                        {
                        }
                        finally
                        {
                            this.instance.activeOperations++;
                            incrementedActiveOperations = true;
                        }

                        this.instance.executorLock.SetupWaiter(ref lockToken);
                    }

                    completeSelf = this.instance.executorLock.EnterAsync(this.timeoutHelper.RemainingTime(), ref lockToken, ref ownsLock, lockAcquiredCallback, this);

                    // We don't want to decrement the count if we went async
                    // because the async callback will do the decrement
                    decrementActiveOperations = completeSelf;
                }
                finally
                {
                    if (incrementedActiveOperations && decrementActiveOperations)
                    {
                        lock (this.instance.activeOperationsLock)
                        {
                            this.instance.activeOperations--;
                        }
                    }

                    this.instance.executorLock.CleanupWaiter(lockToken, ref ownsLock);
                }

                if (completeSelf)
                {
                    if (CheckState(ref ownsLock))
                    {
                        Complete(true);
                    }
                }
            }
            public WaitForCanPersistAsyncResult(WorkflowServiceInstance instance, ref bool ownsLock, TimeSpan timeout, AsyncCallback callback, object state)
                : base(callback, state)
            {
                this.instance = instance;
                this.ownsLock = ownsLock;
                this.timeoutHelper = new TimeoutHelper(timeout);

                Fx.Assert(ownsLock, "Must be called under locked!");

                if (WaitForCanPersist())
                {
                    Complete(true);
                }
            }
 public static AbandonAndSuspendAsyncResult Create(WorkflowServiceInstance instance, Exception reason, TimeSpan timeout, AsyncCallback callback, object state)
 {
     AbandonAndSuspendAsyncResult result = new AbandonAndSuspendAsyncResult(instance, reason, callback, state);
     result.Run(timeout);
     return result;
 }
 public UnhandledExceptionAsyncData(WorkflowServiceInstance instance, Exception exception, Activity exceptionSource)
 {
     this.Instance = instance;
     this.Exception = exception;
     this.ExceptionSource = exceptionSource;
 }
 RunAsyncResult(WorkflowServiceInstance instance, Transaction transaction, string operationName, AsyncCallback callback, object state)
     : base(instance, transaction, callback, state)
 {
     this.operationName = operationName;
 }
            public UnloadInstancePolicyHelper(WorkflowServiceInstance instance, TimeSpan timeToPersist, TimeSpan timeToUnload)
            {
                Fx.Assert(instance != null, String.Empty);

                this.instance = instance;
                this.timeToPersist = timeToPersist;
                this.timeToUnload = timeToUnload;
                this.persistEnabled = this.instance.persistenceContext.CanPersist && this.timeToPersist < this.timeToUnload;
                this.unloadEnabled = this.instance.persistenceContext.CanPersist && this.timeToUnload < TimeSpan.MaxValue;

                if (this.persistEnabled)
                {
                    this.persistTimer = new IOThreadTimer(onTimerCallback, new Action(Persist), true);
                }
                if (this.unloadEnabled)
                {
                    this.unloadTimer = new IOThreadTimer(onTimerCallback, new Action(Unload), true);
                }
            }
 public static RunAsyncResult Create(WorkflowServiceInstance instance, Transaction transaction, string operationName, TimeSpan timeout, AsyncCallback callback, object state)
 {
     RunAsyncResult result = new RunAsyncResult(instance, transaction, operationName, callback, state);
     result.Run(timeout);
     return result;
 }
 public UnhandledExceptionPolicyHelper(WorkflowServiceInstance instance, WorkflowUnhandledExceptionAction action)
 {
     Fx.Assert(instance != null, "instance must not be null!");
     Fx.Assert(WorkflowUnhandledExceptionActionHelper.IsDefined(action), action + " is invalid!");
     this.instance = instance;
     this.action = action;
 }
 SuspendAsyncResult(WorkflowServiceInstance instance, bool isUnlocked, string reason, Transaction transaction, AsyncCallback callback, object state)
     : base(instance, transaction, callback, state)
 {
     this.isUnlocked = isUnlocked;
     this.reason = reason;
 }
            bool TryEnlistContext()
            {
                IAsyncResult enlistResult = null;
                bool tryAgain = false;

                // We need to enlist for the transaction. This call will wait until
                // we obtain the transaction lock on the PersistenceContext, too. If there is no current transaction, this call
                // will still wait to get the transaction lock, but we not create an enlistment.
                using (PrepareTransactionalCall(this.transaction))
                {
                    try
                    {
                        enlistResult = this.persistenceContext.BeginEnlist(this.timeout, PrepareAsyncCompletion(handleEndEnlistContext), this);
                    }
                    catch (ObjectDisposedException)
                    {
                        tryAgain = true;
                    }
                    catch (CommunicationObjectAbortedException)
                    {
                        throw FxTrace.Exception.AsError(new OperationCanceledException(SR.DefaultAbortReason));
                    }
                }

                if (tryAgain)
                {
                    this.referenceAcquired = false;
                    this.durableInstance = null;
                    return this.GetInstance();
                }
                else
                {
                    return SyncContinue(enlistResult);
                }
            }
 public static SuspendAsyncResult Create(WorkflowServiceInstance instance, bool isUnlocked, string reason, Transaction transaction, TimeSpan timeout, AsyncCallback callback, object state)
 {
     SuspendAsyncResult result = new SuspendAsyncResult(instance, isUnlocked, reason, transaction, callback, state);
     result.Run(timeout);
     return result;
 }
 //This is the dispatch call for Non-IWorkflowInstanceManagement Operations.
 protected virtual IAsyncResult OnBeginServiceOperation(WorkflowServiceInstance durableInstance,
     OperationContext operationContext, object[] inputs, Transaction currentTransaction, IInvokeReceivedNotification notification,
     TimeSpan timeout, AsyncCallback callback, object state)
 {
     return new ServiceOperationAsyncResult(this.innerInvoker, durableInstance, inputs, operationContext, currentTransaction, notification,
         callback, state);
 }
 UnsuspendAsyncResult(WorkflowServiceInstance instance, Transaction transaction, AsyncCallback callback, object state)
     : base(instance, transaction, callback, state)
 {
 }
            public ServiceOperationAsyncResult(IOperationInvoker innerInvoker, WorkflowServiceInstance durableInstance,
                object[] inputs, OperationContext operationContext, Transaction currentTransaction, IInvokeReceivedNotification notification,
                AsyncCallback callback, object state)
                : base(callback, state)
            {
                this.durableInstance = durableInstance;
                this.operationContext = operationContext;
                this.inputs = inputs;
                this.innerInvoker = innerInvoker;
                this.currentTransaction = currentTransaction;
                this.notification = notification;

                if (innerInvoker == null)
                {
                    //Mode2: Derived invoker should have handled this call.
                    throw Fx.AssertAndThrow("Cannot reach this path without innerInvoker");
                }

                if (this.innerInvoker.IsSynchronous)
                {
                    TransactionScope scope = TransactionHelper.CreateTransactionScope(this.currentTransaction);
                    try
                    {
                        using (new OperationContextScopeHelper(this.operationContext))
                        {
                            IManualConcurrencyOperationInvoker manualInvoker = this.innerInvoker as IManualConcurrencyOperationInvoker;
                            if (manualInvoker != null)
                            {
                                this.returnValue = manualInvoker.Invoke(this.durableInstance, this.inputs, this.notification, out this.outputs);
                            }
                            else
                            {
                                this.returnValue = this.innerInvoker.Invoke(this.durableInstance, this.inputs, out this.outputs);
                            }
                        }
                    }
                    finally
                    {
                        TransactionHelper.CompleteTransactionScope(ref scope);
                    }
                    this.Complete(true);
                }
                else
                {
                    IAsyncResult result;
                    using (PrepareTransactionalCall(this.currentTransaction))
                    {
                        using (new OperationContextScopeHelper(this.operationContext))
                        {
                            IManualConcurrencyOperationInvoker manualInvoker = this.innerInvoker as IManualConcurrencyOperationInvoker;
                            if (manualInvoker != null)
                            {
                                result = manualInvoker.InvokeBegin(this.durableInstance, this.inputs, this.notification, this.PrepareAsyncCompletion(handleEndInvoke), this);
                            }
                            else
                            {
                                result = this.innerInvoker.InvokeBegin(this.durableInstance, this.inputs, this.PrepareAsyncCompletion(handleEndInvoke), this);
                            }
                        }
                    }
                    if (SyncContinue(result))
                    {
                        this.Complete(true);
                    }
                }
            }
 public static UnsuspendAsyncResult Create(WorkflowServiceInstance instance, Transaction transaction, TimeSpan timeout, AsyncCallback callback, object state)
 {
     UnsuspendAsyncResult result = new UnsuspendAsyncResult(instance, transaction, callback, state);
     result.Run(timeout);
     return result;
 }