Exemplo n.º 1
0
        private static bool TryNumericConversion <T>(object source, out T result)
        {
            Fx.Assert(source != null, "caller must verify");
            TypeCode sourceTypeCode      = source.GetType().GetTypeCode();
            TypeCode destinationTypeCode = typeof(T).GetTypeCode();

            switch (sourceTypeCode)
            {
            case TypeCode.SByte:
            {
                SByte sbyteSource = (SByte)source;
                switch (destinationTypeCode)
                {
                case TypeCode.Int16:
                    result = (T)(object)(Int16)sbyteSource;
                    return(true);

                case TypeCode.Int32:
                    result = (T)(object)(Int32)sbyteSource;
                    return(true);

                case TypeCode.Int64:
                    result = (T)(object)(Int64)sbyteSource;
                    return(true);

                case TypeCode.Single:
                    result = (T)(object)(Single)sbyteSource;
                    return(true);

                case TypeCode.Double:
                    result = (T)(object)(Double)sbyteSource;
                    return(true);

                case TypeCode.Decimal:
                    result = (T)(object)(Decimal)sbyteSource;
                    return(true);
                }
                break;
            }

            case TypeCode.Byte:
            {
                Byte byteSource = (Byte)source;
                switch (destinationTypeCode)
                {
                case TypeCode.Int16:
                    result = (T)(object)(Int16)byteSource;
                    return(true);

                case TypeCode.UInt16:
                    result = (T)(object)(UInt16)byteSource;
                    return(true);

                case TypeCode.Int32:
                    result = (T)(object)(Int32)byteSource;
                    return(true);

                case TypeCode.UInt32:
                    result = (T)(object)(UInt32)byteSource;
                    return(true);

                case TypeCode.Int64:
                    result = (T)(object)(Int64)byteSource;
                    return(true);

                case TypeCode.UInt64:
                    result = (T)(object)(UInt64)byteSource;
                    return(true);

                case TypeCode.Single:
                    result = (T)(object)(Single)byteSource;
                    return(true);

                case TypeCode.Double:
                    result = (T)(object)(Double)byteSource;
                    return(true);

                case TypeCode.Decimal:
                    result = (T)(object)(Decimal)byteSource;
                    return(true);
                }
                break;
            }

            case TypeCode.Int16:
            {
                Int16 int16Source = (Int16)source;
                switch (destinationTypeCode)
                {
                case TypeCode.Int32:
                    result = (T)(object)(Int32)int16Source;
                    return(true);

                case TypeCode.Int64:
                    result = (T)(object)(Int64)int16Source;
                    return(true);

                case TypeCode.Single:
                    result = (T)(object)(Single)int16Source;
                    return(true);

                case TypeCode.Double:
                    result = (T)(object)(Double)int16Source;
                    return(true);

                case TypeCode.Decimal:
                    result = (T)(object)(Decimal)int16Source;
                    return(true);
                }
                break;
            }

            case TypeCode.UInt16:
            {
                UInt16 uint16Source = (UInt16)source;
                switch (destinationTypeCode)
                {
                case TypeCode.Int32:
                    result = (T)(object)(Int32)uint16Source;
                    return(true);

                case TypeCode.UInt32:
                    result = (T)(object)(UInt32)uint16Source;
                    return(true);

                case TypeCode.Int64:
                    result = (T)(object)(Int64)uint16Source;
                    return(true);

                case TypeCode.UInt64:
                    result = (T)(object)(UInt64)uint16Source;
                    return(true);

                case TypeCode.Single:
                    result = (T)(object)(Single)uint16Source;
                    return(true);

                case TypeCode.Double:
                    result = (T)(object)(Double)uint16Source;
                    return(true);

                case TypeCode.Decimal:
                    result = (T)(object)(Decimal)uint16Source;
                    return(true);
                }
                break;
            }

            case TypeCode.Int32:
            {
                Int32 int32Source = (Int32)source;
                switch (destinationTypeCode)
                {
                case TypeCode.Int64:
                    result = (T)(object)(Int64)int32Source;
                    return(true);

                case TypeCode.Single:
                    result = (T)(object)(Single)int32Source;
                    return(true);

                case TypeCode.Double:
                    result = (T)(object)(Double)int32Source;
                    return(true);

                case TypeCode.Decimal:
                    result = (T)(object)(Decimal)int32Source;
                    return(true);
                }
                break;
            }

            case TypeCode.UInt32:
            {
                UInt32 uint32Source = (UInt32)source;
                switch (destinationTypeCode)
                {
                case TypeCode.UInt32:
                    result = (T)(object)(UInt32)uint32Source;
                    return(true);

                case TypeCode.Int64:
                    result = (T)(object)(Int64)uint32Source;
                    return(true);

                case TypeCode.UInt64:
                    result = (T)(object)(UInt64)uint32Source;
                    return(true);

                case TypeCode.Single:
                    result = (T)(object)(Single)uint32Source;
                    return(true);

                case TypeCode.Double:
                    result = (T)(object)(Double)uint32Source;
                    return(true);

                case TypeCode.Decimal:
                    result = (T)(object)(Decimal)uint32Source;
                    return(true);
                }
                break;
            }

            case TypeCode.Int64:
            {
                Int64 int64Source = (Int64)source;
                switch (destinationTypeCode)
                {
                case TypeCode.Single:
                    result = (T)(object)(Single)int64Source;
                    return(true);

                case TypeCode.Double:
                    result = (T)(object)(Double)int64Source;
                    return(true);

                case TypeCode.Decimal:
                    result = (T)(object)(Decimal)int64Source;
                    return(true);
                }
                break;
            }

            case TypeCode.UInt64:
            {
                UInt64 uint64Source = (UInt64)source;
                switch (destinationTypeCode)
                {
                case TypeCode.Single:
                    result = (T)(object)(Single)uint64Source;
                    return(true);

                case TypeCode.Double:
                    result = (T)(object)(Double)uint64Source;
                    return(true);

                case TypeCode.Decimal:
                    result = (T)(object)(Decimal)uint64Source;
                    return(true);
                }
                break;
            }

            case TypeCode.Char:
            {
                Char charSource = (Char)source;
                switch (destinationTypeCode)
                {
                case TypeCode.UInt16:
                    result = (T)(object)(UInt16)charSource;
                    return(true);

                case TypeCode.Int32:
                    result = (T)(object)(Int32)charSource;
                    return(true);

                case TypeCode.UInt32:
                    result = (T)(object)(UInt32)charSource;
                    return(true);

                case TypeCode.Int64:
                    result = (T)(object)(Int64)charSource;
                    return(true);

                case TypeCode.UInt64:
                    result = (T)(object)(UInt64)charSource;
                    return(true);

                case TypeCode.Single:
                    result = (T)(object)(Single)charSource;
                    return(true);

                case TypeCode.Double:
                    result = (T)(object)(Double)charSource;
                    return(true);

                case TypeCode.Decimal:
                    result = (T)(object)(Decimal)charSource;
                    return(true);
                }
                break;
            }

            case TypeCode.Single:
            {
                if (destinationTypeCode == TypeCode.Double)
                {
                    result = (T)(object)(Double)(Single)source;
                    return(true);
                }
                break;
            }
            }

            result = default(T);
            return(false);
        }
Exemplo n.º 2
0
        private static bool CanCompensationOrConfirmationHandlerReferenceAddedSymbols(InstanceList instanceList, DynamicUpdateMap rootUpdateMap, IdSpace rootIdSpace, List <ActivityInstance> secondaryRootInstances, ref Collection <ActivityBlockingUpdate> updateErrors)
        {
            for (int j = 0; j < instanceList.Count; j++)
            {
                ActivityInstance activityInstance = instanceList[j] as ActivityInstance;
                if (activityInstance == null || !IsNonDefaultSecondaryRoot(activityInstance, secondaryRootInstances))
                {
                    continue;
                }

                // here, find out if the given non-default secondary root references an environment to which a symbol is to be added via DU.
                // we start from a secondary root instead of starting from the enviroment with the already completed owner that was added symbols.
                // It is becuase for the case of adding symbols to noSymbols activities, the environment doesn't even exist from which we can start looking for referencing secondary root.

                int[] secondaryRootOriginalQID = new QualifiedId(instanceList.ActivityId).AsIDArray();

                Fx.Assert(secondaryRootOriginalQID != null && secondaryRootOriginalQID.Length > 1,
                          "CompensationParticipant is always an implementation child of a CompensableActivity, therefore it's IdSpace must be at least one level deep.");

                int[] parentOfSecondaryRootOriginalQID = new int[secondaryRootOriginalQID.Length - 1];
                Array.Copy(secondaryRootOriginalQID, parentOfSecondaryRootOriginalQID, secondaryRootOriginalQID.Length - 1);

                List <int> currentQIDBuilder = new List <int>();
                for (int i = 0; i < parentOfSecondaryRootOriginalQID.Length; i++)
                {
                    //
                    // for each iteration of this for-loop,
                    //  we are finding out if at every IdSpace level the map has any map entry whose activity has the CompensableActivity as an implementation decendant.
                    //  The map may not exist for every IdSpace between the root and the CompensableActivity.
                    //  If the matching map and the entry is found, then we find out if that matching entry's activity is a public decendant of any NoSymbols activity DU is to add variables or arguments to.
                    //
                    // This walk on the definition activity tree determines the hypothetical execution-time chain of instances and environments.
                    // The ultimate goal is to prevent adding variables or arguments to a NoSymbols activity which has already completed,
                    //  but its decendant CompensableActivity's compensation or confirmation handlers in the future may need to reference the added variables or arguments.

                    currentQIDBuilder.Add(parentOfSecondaryRootOriginalQID[i]);

                    DynamicUpdateMap.UpdatedActivity updatedActivity = rootUpdateMap.GetUpdatedActivity(new QualifiedId(currentQIDBuilder.ToArray()), rootIdSpace);
                    if (updatedActivity.MapEntry != null)
                    {
                        // the activity of this entry either has the CompensableActivity as an implementation decendant, or is the CompensableActivity itself.

                        // walk the same-IdSpace-parent chain of the entry,
                        // look for an entry whose EnvironmentUpdateMap.IsAdditionToNoSymbols is true.
                        DynamicUpdateMapEntry entry = updatedActivity.MapEntry;
                        do
                        {
                            if (!entry.IsRemoval && entry.HasEnvironmentUpdates && entry.EnvironmentUpdateMap.IsAdditionToNoSymbols)
                            {
                                int[] noSymbolAddActivityIDArray = currentQIDBuilder.ToArray();
                                noSymbolAddActivityIDArray[noSymbolAddActivityIDArray.Length - 1] = entry.OldActivityId;
                                QualifiedId noSymbolAddActivityQID = new QualifiedId(noSymbolAddActivityIDArray);
                                DynamicUpdateMap.UpdatedActivity noSymbolAddUpdatedActivity = rootUpdateMap.GetUpdatedActivity(noSymbolAddActivityQID, rootIdSpace);

                                AddBlockingActivity(ref updateErrors, noSymbolAddUpdatedActivity, noSymbolAddActivityQID, SR.VariableOrArgumentAdditionToReferencedEnvironmentNoDUSupported, null);
                                return(true);
                            }

                            entry = entry.Parent;
                        } while (entry != null);
                    }
                }
            }

            return(false);
        }
Exemplo n.º 3
0
        // this is called after all instances have been loaded and fixedup
        public void UpdateInstanceByActivityParticipation(ActivityExecutor activityExecutor, DynamicUpdateMap rootMap, ref Collection <ActivityBlockingUpdate> updateErrors)
        {
            foreach (InstanceListNeedingUpdate participant in this.updateList)
            {
                if (participant.NothingChanged || participant.ParentIdShiftOnly)
                {
                    Fx.Assert(participant.UpdateMap == null && participant.MapEntry == null, "UpdateMap and MapEntry must be null if we are here.");

                    // create a temporary NoChanges UpdateMap as well as a temporary no change MapEntry
                    // so that we can create a NativeActivityUpdateContext object in order to invoke UpdateInstance() on an activity which
                    // doesn't have a corresponding map and an map entry.
                    // The scenario enabled here is scheduling a newly added reference branch to a Parallel inside an activity's implementation.
                    participant.UpdateMap = DynamicUpdateMap.DummyMap;
                    participant.MapEntry  = DynamicUpdateMapEntry.DummyMapEntry;
                }

                // now let activities participate in update
                for (int i = 0; i < participant.InstanceList.Count; i++)
                {
                    ActivityInstance instance = participant.InstanceList[i] as ActivityInstance;
                    if (instance == null)
                    {
                        continue;
                    }

                    IInstanceUpdatable activity = instance.Activity as IInstanceUpdatable;
                    if (activity != null && instance.SubState == ActivityInstance.Substate.Executing)
                    {
                        NativeActivityUpdateContext updateContext = new NativeActivityUpdateContext(this, activityExecutor, instance, participant.UpdateMap, participant.MapEntry, rootMap);
                        try
                        {
                            activity.InternalUpdateInstance(updateContext);

                            if (updateContext.IsUpdateDisallowed)
                            {
                                ActivityBlockingUpdate.AddBlockingActivity(ref updateErrors, instance.Activity, new QualifiedId(participant.OriginalId).ToString(), updateContext.DisallowedReason, instance.Id);
                                continue;
                            }
                        }
                        catch (Exception e)
                        {
                            if (Fx.IsFatal(e))
                            {
                                throw;
                            }

                            throw FxTrace.Exception.AsError(new InstanceUpdateException(SR.NativeActivityUpdateInstanceThrewException(e.Message), e));
                        }
                        finally
                        {
                            updateContext.Dispose();
                        }
                    }
                }
            }

            // Schedule evaluation of newly added arguments and newly added variables.
            // This needs to happen after all the invokations of UpdateInstance above, so that newly
            // added arguments and newly added variables get evaluated before any newly added activities get executed.
            // We iterate the list in reverse so that parents are always scheduled after (and thus
            // execute before) their children, which may depend on the parents.
            for (int i = this.updateList.Count - 1; i >= 0; i--)
            {
                InstanceListNeedingUpdate participant = this.updateList[i];

                if (!participant.MapEntryExists)
                {
                    // if the given InstanceList has no map entry,
                    // then there is no new LocationReferences to resolve.
                    continue;
                }

                Fx.Assert(participant.MapEntry != null, "MapEntry must be non-null here.");
                if (!participant.MapEntry.HasEnvironmentUpdates)
                {
                    // if there is no environment updates for this MapEntry,
                    // then there is no new LocationReferences to resolve.
                    continue;
                }

                for (int j = 0; j < participant.InstanceList.Count; j++)
                {
                    ActivityInstance instance = participant.InstanceList[j] as ActivityInstance;
                    if (instance == null || instance.SubState != ActivityInstance.Substate.Executing)
                    {
                        // if the given ActivityInstance is not in Substate.Executing,
                        // then, do not try to resolve new LocationReferences
                        continue;
                    }

                    List <int> addedArgumentIndexes;
                    List <int> addedVariableIndexes;
                    List <int> addedPrivateVariableIndexes;

                    EnvironmentUpdateMap envMap = participant.MapEntry.EnvironmentUpdateMap;

                    if (envMap.HasVariableEntries && TryGatherSchedulableExpressions(envMap.VariableEntries, out addedVariableIndexes))
                    {
                        // schedule added variable default expressions
                        instance.ResolveNewVariableDefaultsDuringDynamicUpdate(activityExecutor, addedVariableIndexes, false);
                    }

                    if (envMap.HasPrivateVariableEntries && TryGatherSchedulableExpressions(envMap.PrivateVariableEntries, out addedPrivateVariableIndexes))
                    {
                        // schedule added private variable default expressions
                        // HasPrivateMemberChanged() check disallows addition of private variable default that offsets the private IdSpace,
                        // However, the added private variable default expression can be an imported activity, which has no affect on the private IdSpace.
                        // For such case, we want to be able to schedule the imported default expressions here.
                        instance.ResolveNewVariableDefaultsDuringDynamicUpdate(activityExecutor, addedPrivateVariableIndexes, true);
                    }

                    if (envMap.HasArgumentEntries && TryGatherSchedulableExpressions(envMap.ArgumentEntries, out addedArgumentIndexes))
                    {
                        // schedule added arguments
                        instance.ResolveNewArgumentsDuringDynamicUpdate(activityExecutor, addedArgumentIndexes);
                    }
                }
            }
        }
Exemplo n.º 4
0
 internal void PurgeSingleBookmark(Bookmark bookmark)
 {
     Fx.Assert(this.bookmarks.ContainsKey(bookmark) && object.ReferenceEquals(bookmark, this.bookmarks[bookmark].Bookmark), "Something went wrong with our housekeeping - it must exist and must be our intenral reference");
     UpdateExclusiveHandleList(bookmark);
     this.bookmarks.Remove(bookmark);
 }
Exemplo n.º 5
0
        internal void Update(EnvironmentUpdateMap map, Activity activity)
        {
            //                    arguments     public variables      private variables    RuntimeDelegateArguments
            //  Locations array:  AAAAAAAAAA   VVVVVVVVVVVVVVVVVVVVVV PPPPPPPPPPPPPPPPPPP  DDDDDDDDDDDDDDDDDDDDDDDDDDDDDD

            int actualRuntimeDelegateArgumentCount = activity.HandlerOf == null ? 0 : activity.HandlerOf.RuntimeDelegateArguments.Count;

            if (map.NewArgumentCount != activity.RuntimeArguments.Count ||
                map.NewVariableCount != activity.RuntimeVariables.Count ||
                map.NewPrivateVariableCount != activity.ImplementationVariables.Count ||
                map.RuntimeDelegateArgumentCount != actualRuntimeDelegateArgumentCount)
            {
                throw FxTrace.Exception.AsError(new InstanceUpdateException(SR.InvalidUpdateMap(
                                                                                SR.WrongEnvironmentCount(activity, map.NewArgumentCount, map.NewVariableCount, map.NewPrivateVariableCount, map.RuntimeDelegateArgumentCount,
                                                                                                         activity.RuntimeArguments.Count, activity.RuntimeVariables.Count, activity.ImplementationVariables.Count, actualRuntimeDelegateArgumentCount))));
            }

            int expectedLocationCount = map.OldArgumentCount + map.OldVariableCount + map.OldPrivateVariableCount + map.RuntimeDelegateArgumentCount;

            int actualLocationCount;

            if (this.locations == null)
            {
                if (this.singleLocation == null)
                {
                    // we can hit this condition when the root activity instance has zero symbol.
                    actualLocationCount = 0;
                }
                else
                {
                    actualLocationCount = 1;

                    // temporarily normalize to locations array for the sake of environment update processing
                    this.locations      = new Location[] { this.singleLocation };
                    this.singleLocation = null;
                }
            }
            else
            {
                Fx.Assert(this.singleLocation == null, "locations and singleLocations cannot be non-null at the same time.");
                actualLocationCount = this.locations.Length;
            }

            if (expectedLocationCount != actualLocationCount)
            {
                throw FxTrace.Exception.AsError(new InstanceUpdateException(SR.InvalidUpdateMap(
                                                                                SR.WrongOriginalEnvironmentCount(activity, map.OldArgumentCount, map.OldVariableCount, map.OldPrivateVariableCount, map.RuntimeDelegateArgumentCount,
                                                                                                                 expectedLocationCount, actualLocationCount))));
            }

            Location[] newLocations = null;

            // If newTotalLocations == 0, update will leave us with an empty LocationEnvironment,
            // which is something the runtime would normally never create. This is harmless, but it
            // is a loosening of normal invariants.
            int newTotalLocations = map.NewArgumentCount + map.NewVariableCount + map.NewPrivateVariableCount + map.RuntimeDelegateArgumentCount;

            if (newTotalLocations > 0)
            {
                newLocations = new Location[newTotalLocations];
            }

            UpdateArguments(map, newLocations);
            UnregisterRemovedVariables(map);
            UpdatePublicVariables(map, newLocations, activity);
            UpdatePrivateVariables(map, newLocations, activity);
            CopyRuntimeDelegateArguments(map, newLocations);

            Location newSingleLocation = null;

            if (newTotalLocations == 1)
            {
                newSingleLocation = newLocations[0];
                newLocations      = null;
            }

            this.singleLocation = newSingleLocation;
            this.locations      = newLocations;
        }
Exemplo n.º 6
0
 public void CheckForCancelation()
 {
     Fx.Assert(this.callbackWrapper != null, "We must have a callback wrapper if we are calling this.");
     this.callbackWrapper.CheckForCancelation();
 }
        public override bool Execute(ActivityExecutor executor, BookmarkManager bookmarkManager)
        {
            Fx.Assert("Empty work items should never been executed.");

            return(true);
        }
Exemplo n.º 8
0
 private void SetDeadline()
 {
     Fx.Assert(!_deadlineSet, "TimeoutHelper deadline set twice.");
     _deadline    = DateTime.UtcNow + _originalTimeout;
     _deadlineSet = true;
 }
Exemplo n.º 9
0
        protected void Complete(bool completedSynchronously)
        {
            if (this.IsCompleted)
            {
                throw Fx.Exception.AsError(new InvalidOperationException(SR.AsyncResultCompletedTwice(this.GetType())));
            }

            //#if DEBUG
            //            this.marker.AsyncResult = null;
            //            this.marker = null;
            //            if (!Fx.FastDebug && completeStack == null)
            //            {
            //                completeStack = new StackTrace();
            //            }
            //#endif

            this.CompletedSynchronously = completedSynchronously;
            if (this.OnCompleting != null)
            {
                // Allow exception replacement, like a catch/throw pattern.
                try
                {
                    this.OnCompleting(this, this._exception);
                }
                catch (Exception exception)
                {
                    if (Fx.IsFatal(exception))
                    {
                        throw;
                    }
                    this._exception = exception;
                }
            }

            if (completedSynchronously)
            {
                // If we completedSynchronously, then there's no chance that the manualResetEvent
                // was created so we don't need to worry about a race condition
                Fx.Assert(this._manualResetEvent == null, "No ManualResetEvent should be created for a synchronous AsyncResult.");
                this.IsCompleted = true;
            }
            else
            {
                lock (this.ThisLock)
                {
                    this.IsCompleted = true;
                    if (this._manualResetEvent != null)
                    {
                        this._manualResetEvent.Set();
                    }
                }
            }

            if (this._callback != null)
            {
                try
                {
                    if (this.VirtualCallback != null)
                    {
                        this.VirtualCallback(this._callback, this);
                    }
                    else
                    {
                        this._callback(this);
                    }
                }
#pragma warning disable 1634
#pragma warning suppress 56500 // transferring exception to another thread
                catch (Exception e)
                {
                    if (Fx.IsFatal(e))
                    {
                        throw;
                    }

                    throw Fx.Exception.AsError(new CallbackException(SR.AsyncCallbackThrewException, e));
                }
#pragma warning restore 1634
            }
        }
Exemplo n.º 10
0
        public BookmarkResumptionResult TryGenerateWorkItem(ActivityExecutor executor, ref Bookmark bookmark, BookmarkScope scope, object value, ActivityInstance isolationInstance, bool nonScopedBookmarksExist, out ActivityExecutionWorkItem workItem)
        {
            Fx.Assert(scope != null, "We should never have a null sub instance.");

            workItem = null;
            BookmarkScope lookupScope = scope;

            if (scope.IsDefault)
            {
                lookupScope = this.defaultScope;
            }

            // We don't really care about the return value since we'll
            // use null to know we should check uninitialized sub instances
            this.bookmarkManagers.TryGetValue(lookupScope, out BookmarkManager manager);

            if (manager == null)
            {
                Fx.Assert(lookupScope != null, "The sub instance should not be default if we are here.");

                BookmarkResumptionResult finalResult = BookmarkResumptionResult.NotFound;

                // Check the uninitialized sub instances for a matching bookmark
                if (this.uninitializedScopes != null)
                {
                    for (int i = 0; i < this.uninitializedScopes.Count; i++)
                    {
                        BookmarkScope uninitializedScope = this.uninitializedScopes[i];

                        Fx.Assert(this.bookmarkManagers.ContainsKey(uninitializedScope), "We must always have the uninitialized sub instances.");
                        BookmarkResumptionResult resumptionResult;
                        if (!this.bookmarkManagers[uninitializedScope].TryGetBookmarkFromInternalList(bookmark, out Bookmark internalBookmark, out BookmarkCallbackWrapper callbackWrapper))
                        {
                            resumptionResult = BookmarkResumptionResult.NotFound;
                        }
                        else if (IsExclusiveScopeUnstable(internalBookmark))
                        {
                            resumptionResult = BookmarkResumptionResult.NotReady;
                        }
                        else
                        {
                            resumptionResult = this.bookmarkManagers[uninitializedScope].TryGenerateWorkItem(executor, true, ref bookmark, value, isolationInstance, out workItem);
                        }

                        if (resumptionResult == BookmarkResumptionResult.Success)
                        {
                            // We are using InitializeBookmarkScopeWithoutKeyAssociation because we know this is a new uninitialized scope and
                            // the key we would associate is already associated. And if we did the association here, the subsequent call to
                            // FlushBookmarkScopeKeys would try to flush it out, but it won't have the transaction correct so will hang waiting for
                            // the transaction that has the PersistenceContext locked to complete. But it won't complete successfully until
                            // we finish processing here.
                            InitializeBookmarkScopeWithoutKeyAssociation(uninitializedScope, scope.Id);

                            // We've found what we were looking for
                            return(BookmarkResumptionResult.Success);
                        }
                        else if (resumptionResult == BookmarkResumptionResult.NotReady)
                        {
                            // This uninitialized sub-instance has a matching bookmark but
                            // it can't currently be resumed.  We won't return BookmarkNotFound
                            // because of this.
                            finalResult = BookmarkResumptionResult.NotReady;
                        }
                        else
                        {
                            if (finalResult == BookmarkResumptionResult.NotFound)
                            {
                                // If we still are planning on returning failure then
                                // we'll incur the cost of seeing if this scope is
                                // stable or not.

                                if (!IsStable(uninitializedScope, nonScopedBookmarksExist))
                                {
                                    // There exists an uninitialized scope which is unstable.
                                    // At the very least this means we'll return NotReady since
                                    // this uninitialized scope might eventually contain this
                                    // bookmark.
                                    finalResult = BookmarkResumptionResult.NotReady;
                                }
                            }
                        }
                    }
                }