private void OnDestroyPage(SecurityCriticalDataForSet <IntPtr> ptsPage, bool enterContext) { Invariant.Assert(ptsPage.Value != IntPtr.Zero, "Invalid page object."); if (!this.Disposed) { Invariant.Assert(this._pages != null, "Collection of pages does not exist."); Invariant.Assert(this._pages.Contains(ptsPage.Value), "Page does not exist."); try { if (enterContext) { this.Enter(); } PTS.Validate(PTS.FsDestroyPage(this._ptsHost.Context, ptsPage.Value)); } finally { if (enterContext) { this.Leave(); } this._pages.Remove(ptsPage.Value); } } }
/// <summary> /// Destroys PTS page. /// </summary> /// <param name="ptsPage">Pointer to PTS Page object that should be destroyed.</param> /// <param name="enterContext">Whether needs to enter PTS Context.</param> private void OnDestroyPage(SecurityCriticalDataForSet <IntPtr> ptsPage, bool enterContext) { Invariant.Assert(ptsPage.Value != IntPtr.Zero, "Invalid page object."); // Dispatcher may invoke this operation when PtsContext is already explicitly // disposed. if (!this.Disposed) { Invariant.Assert(_pages != null, "Collection of pages does not exist."); Invariant.Assert(_pages.Contains(ptsPage.Value), "Page does not exist."); // Destroy given page. // It is necessary to enter PTS Context when executing any PTS methods. try { if (enterContext) { Enter(); } PTS.Validate(PTS.FsDestroyPage(_ptsHost.Context, ptsPage.Value)); } finally { if (enterContext) { Leave(); } _pages.Remove(ptsPage.Value); } } }
public void Dispose() { if (Interlocked.CompareExchange(ref this._disposed, 1, 0) == 0) { try { this.Enter(); for (int i = 0; i < this._pageBreakRecords.Count; i++) { Invariant.Assert((IntPtr)this._pageBreakRecords[i] != IntPtr.Zero, "Invalid break record object"); PTS.Validate(PTS.FsDestroyPageBreakRecord(this._ptsHost.Context, (IntPtr)this._pageBreakRecords[i])); } } finally { this.Leave(); this._pageBreakRecords = null; } try { this.Enter(); for (int i = 0; i < this._pages.Count; i++) { Invariant.Assert((IntPtr)this._pages[i] != IntPtr.Zero, "Invalid break record object"); PTS.Validate(PTS.FsDestroyPage(this._ptsHost.Context, (IntPtr)this._pages[i])); } } finally { this.Leave(); this._pages = null; } if (Invariant.Strict && this._unmanagedHandles != null) { for (int i = 0; i < this._unmanagedHandles.Length; i++) { object obj = this._unmanagedHandles[i].Obj; if (obj != null) { Invariant.Assert(obj is BaseParagraph || obj is Section || obj is LineBreakRecord, "One of PTS Client objects is not properly disposed."); } } } this._ptsHost = null; this._unmanagedHandles = null; this._callbackException = null; this._disposeCompleted = true; } }
//------------------------------------------------------------------- // // Internal Methods // //------------------------------------------------------------------- #region Internal Methods /// <summary> /// Destroy all unmanaged resources associated with the PtsContext. /// </summary> public void Dispose() { int index; // Do actual dispose only once. if (Interlocked.CompareExchange(ref _disposed, 1, 0) == 0) { // Destroy all page break records. The collection is allocated during creation // of the context, and can be only destroyed during dispose process. // It is necessary to enter PTS Context when executing any PTS methods. try { Enter(); for (index = 0; index < _pageBreakRecords.Count; index++) { Invariant.Assert(((IntPtr)_pageBreakRecords[index]) != IntPtr.Zero, "Invalid break record object"); PTS.Validate(PTS.FsDestroyPageBreakRecord(_ptsHost.Context, (IntPtr)_pageBreakRecords[index])); } } finally { Leave(); _pageBreakRecords = null; } // Destroy all pages. The collection is allocated during creation // of the context, and can be only destroyed during dispose process. // It is necessary to enter PTS Context when executing any PTS methods. try { Enter(); for (index = 0; index < _pages.Count; index++) { Invariant.Assert(((IntPtr)_pages[index]) != IntPtr.Zero, "Invalid break record object"); PTS.Validate(PTS.FsDestroyPage(_ptsHost.Context, (IntPtr)_pages[index])); } } finally { Leave(); _pages = null; } if (Invariant.Strict && _unmanagedHandles != null) { // Verify that PtsContext does not contain any reference to objects. // Because order of finalizers is not deterministic, only objects // that can be part of the NameTable are allowed here. for (index = 0; index < _unmanagedHandles.Length; ++index) { Object obj = _unmanagedHandles[index].Obj; if (obj != null) { Invariant.Assert( obj is BaseParagraph || obj is Section || obj is MS.Internal.PtsHost.LineBreakRecord, // Suppress line break record leak, looks like a PTS issue but we cannot // get a firm repro for now. Workaround for bug #1294210. "One of PTS Client objects is not properly disposed."); #if DEBUG // Make sure that FigureParagraphs are only used by TextParagraph if (obj is FigureParagraph || obj is FloaterParagraph) { bool found = false; for (int i = 0; i < _unmanagedHandles.Length; ++i) { Object objDbg = _unmanagedHandles[i].Obj; if (objDbg is TextParagraph) { List <AttachedObject> attachedObjects = ((TextParagraph)objDbg).AttachedObjectDbg; if (attachedObjects != null) { foreach (AttachedObject attachedObject in attachedObjects) { if (attachedObject.Para == obj) { found = true; break; } } } if (found) { break; } } } Invariant.Assert(found, "FigureParagraph is not properly disposed."); } #endif } } } _ptsHost = null; _unmanagedHandles = null; _callbackException = null; _disposeCompleted = true; } }