// This happens only when the transaction under which the handle was bound is committed. internal bool TryCompleteBind(ref InstanceHandleReference reference, ref List <InstanceHandleReference> handlesPendingResolution, out InstanceHandle handleToFree) { Fx.Assert(reference != null, "Bind wasn't registered - RegisterStartBind must be called."); Fx.Assert(reference.InstanceHandle != null, "Cannot cancel and complete a bind."); Fx.Assert(reference.InstanceHandle.Version != -1, "Handle state must be set first."); Fx.Assert(object.ReferenceEquals(this, reference.InstanceHandle.Owner), "TryCompleteBind called on the wrong owner for a handle."); Fx.Assert(!(reference is LockResolutionMarker) || ((LockResolutionMarker)reference).NonConflicting, "How did a Version get set if we're still resolving."); handleToFree = null; lock (HandlesLock) { try { InstanceHandle existingHandle; if (BoundHandles.TryGetValue(reference.InstanceHandle.Id, out existingHandle)) { Fx.AssertAndFailFast(!object.ReferenceEquals(existingHandle, reference.InstanceHandle), "InstanceStore lock state is not correct."); if (existingHandle.Version <= 0 || reference.InstanceHandle.Version <= 0) { if (existingHandle.Version != 0 || reference.InstanceHandle.Version != 0) { throw Fx.Exception.AsError(new InvalidOperationException(SRCore.InvalidLockToken)); } reference.InstanceHandle.ConflictingHandle = existingHandle; return(false); } if (existingHandle.Version > reference.InstanceHandle.Version) { reference.InstanceHandle.ConflictingHandle = existingHandle; return(false); } if (existingHandle.Version < reference.InstanceHandle.Version) { existingHandle.ConflictingHandle = reference.InstanceHandle; handleToFree = existingHandle; BoundHandles[reference.InstanceHandle.Id] = reference.InstanceHandle; return(true); } if (existingHandle.Version == reference.InstanceHandle.Version) { // This could be a case of amnesia (backup / restore). throw Fx.Exception.AsError(new InvalidOperationException(SRCore.InstanceStoreBoundSameVersionTwice)); } throw Fx.AssertAndThrow("All cases covered above."); } else { BoundHandles.Add(reference.InstanceHandle.Id, reference.InstanceHandle); return(true); } } finally { CancelReference(ref reference, ref handlesPendingResolution); } } }