/// <summary> /// Removes the child. /// </summary> /// <param name="child">The child.</param> public void RemoveChild(IPersistedData child) { if (child == null) { throw new ArgumentNullException("child"); } if (child.Parent == null) { return; } if (child.Parent != this) { RmAssert.Fail("cannot remove a node that is not a child."); } child.Parent = null; this.childrenCount--; }
/// <summary> /// closes this locklist, and commits changes and unlocks all if context gets down to 0 /// </summary> /// <param name="task">async task to indicate the completion of the replication on output</param> /// <returns>true if it needs to be disposed</returns> public bool Complete(out Task task) { ManualResetEvent ev = null; bool abort = this.IsMarkedForAbort(); task = Task.FromResult(0); try { // if this is an abort and we are not in the topmost context, lock down this object so nothing else can be done other that unwind and abort if (abort) { if (this.onAbort != null) { // CAREFUL! this iteration will execute IN REVERSE ORDER. Because elements were inserted each on the first place!!! foreach (Action elem in this.onAbort) { elem(); } } if (this.changelist != null) { this.changelist.Abort(); } } else { List <Action> actions = this.onCommit; this.onCommit = null; // execute all oncommit actions now if (actions != null) { foreach (Action act in actions) { act(); } } if (this.changelist != null && !this.onlyOnEphemeral) { try { if (this.FinishSynchronous) { ev = ManualResetEventPool.InstancePool.GetOne(); this.changelist.CommitSync(this.TxId, ev, out task); } else { this.changelist.Commit(this.TxId, out task); } } catch (Exception e) { RmAssert.Fail("Commit failed: " + e); } RingMasterServerInstrumentation.Instance.OnTxCommitted(); } } } finally { // make sure we unlock the tree in all cases this.changelist = null; this.onAbort = null; this.onCommit = null; this.lockCollections.Release(); } if (ev != null) { ManualResetEventPool.InstancePool.WaitOneAndReturn(ref ev); } return(true); }