Skip to content

Commit 70962a5

Browse files
authored
Release font resources to fix memory leak (#9250)
* release font resources to fix memory leak * add font resources to package writer * fixing indentation * reverting unintended change
1 parent d9b45ec commit 70962a5

File tree

3 files changed

+41
-7
lines changed

3 files changed

+41
-7
lines changed

src/Microsoft.DotNet.Wpf/src/ReachFramework/Serialization/RCW/IXpsOMPartUriCollection.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,16 @@ namespace System.Windows.Xps.Serialization.RCW
2323
[ComImport]
2424
internal interface IXpsOMPartUriCollection
2525
{
26-
void Append([In] IOpcPartUri partUri);
26+
uint GetCount();
2727

2828
IOpcPartUri GetAt([In] uint index);
2929

30-
uint GetCount();
31-
3230
void InsertAt([In] uint index, [In] IOpcPartUri partUri);
3331

3432
void RemoveAt([In] uint index);
3533

3634
void SetAt([In] uint index, [In] IOpcPartUri partUri);
35+
36+
void Append([In] IOpcPartUri partUri);
3737
}
3838
}

src/Microsoft.DotNet.Wpf/src/ReachFramework/Serialization/manager/XpsOMPackagingPolicy.cs

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ IXpsDocumentPackageTarget packageTarget
3838
_xpsOMFactory = _packageTarget.GetXpsOMFactory();
3939

4040
_xpsPartResources = _xpsOMFactory.CreatePartResources();
41+
_discardableResourceParts = _xpsOMFactory.CreatePartUriCollection();
4142

4243
}
4344
catch (COMException)
@@ -65,7 +66,8 @@ IXpsDocumentPackageTarget packageTarget
6566
try
6667
{
6768
IOpcPartUri partUri = GenerateIOpcPartUri(XpsS0Markup.DocumentSequenceContentType);
68-
_currentFixedDocumentSequenceWriter = _packageTarget.GetXpsOMPackageWriter(partUri, null);
69+
IOpcPartUri discardControlPartUri = GenerateIOpcPartUri(XpsS0Markup.DiscardContentType);
70+
_currentFixedDocumentSequenceWriter = _packageTarget.GetXpsOMPackageWriter(partUri, discardControlPartUri);
6971
if (_printQueue != null)
7072
{
7173
((PrintQueue)_printQueue).XpsOMPackageWriter = _currentFixedDocumentSequenceWriter;
@@ -516,6 +518,7 @@ string resourceId
516518
{
517519
if (resourceStreamCacheItem.Release() == 0)
518520
{
521+
ReleaseFontResource(resourceStreamCacheItem.XpsResourceStream.Uri);
519522
resourceStreamCacheItem.XpsResourceStream.Stream.Dispose();
520523
resourceStreamCacheItem.XpsResourceStream.Initialize();
521524
_fontsCache.Remove(resourceId);
@@ -527,6 +530,32 @@ string resourceId
527530
}
528531
}
529532

533+
/// <SecurityNote>
534+
/// Critical: Calls into COM
535+
/// Safe: Does not expose critical resources to the caller
536+
/// </SecurityNote>
537+
[SecuritySafeCritical]
538+
void ReleaseFontResource(Uri uri)
539+
{
540+
IXpsOMFontResourceCollection fontCollection = _xpsPartResources.GetFontResources();
541+
IOpcPartUri partUri = GenerateIOpcPartUri(uri);
542+
IXpsOMFontResource fontResourceToRemove = fontCollection.GetByPartName(partUri);
543+
_discardableResourceParts.Append(partUri);
544+
if (fontResourceToRemove != null)
545+
{
546+
for (uint i = 0, n = fontCollection.GetCount(); i < n; ++i)
547+
{
548+
IXpsOMFontResource fontResource = fontCollection.GetAt(i);
549+
if (fontResource == fontResourceToRemove)
550+
{
551+
_currentFixedDocumentSequenceWriter.AddResource(fontResource);
552+
fontCollection.RemoveAt(i);
553+
break;
554+
}
555+
}
556+
}
557+
}
558+
530559
public
531560
override
532561
XpsResourceStream
@@ -860,7 +889,12 @@ ContentType contentType
860889
SetHyperlinkTargetsForCurrentPage();
861890

862891
XPS_SIZE xpsSize = new XPS_SIZE() { width = (float)_currentPageSize.Width, height = (float)_currentPageSize.Height };
863-
_currentFixedDocumentSequenceWriter.AddPage(_currentFixedPageWriter, xpsSize, null, null, printTicketResource, null);
892+
_currentFixedDocumentSequenceWriter.AddPage(_currentFixedPageWriter, xpsSize, _discardableResourceParts, null, printTicketResource, null);
893+
894+
while (_discardableResourceParts.GetCount() > 0)
895+
{
896+
_discardableResourceParts.RemoveAt(0);
897+
}
864898
}
865899
catch (COMException)
866900
{
@@ -906,6 +940,7 @@ ContentType contentType
906940
private IXpsOMPartResources _xpsPartResources;
907941
private IXpsOMPackageWriter _currentFixedDocumentSequenceWriter;
908942
private IXpsOMPage _currentFixedPageWriter;
943+
private IXpsOMPartUriCollection _discardableResourceParts;
909944
private XPS_IMAGE_TYPE _currentImageType;
910945

911946
// Writer reference counts

src/Microsoft.DotNet.Wpf/src/ReachFramework/Serialization/manager/XpsOMSerializationManager.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -377,8 +377,6 @@ Type writerType
377377
{
378378
Toolbox.EmitEvent(EventTrace.Event.WClientDRXReleaseWriterStart);
379379

380-
signalReleaseToFontService(writerType);
381-
382380
//
383381
// Allow the packaging policy to release the stream
384382
//
@@ -394,6 +392,7 @@ Type writerType
394392
}
395393
}
396394

395+
signalReleaseToFontService(writerType);
397396
Toolbox.EmitEvent(EventTrace.Event.WClientDRXReleaseWriterEnd);
398397
}
399398

0 commit comments

Comments
 (0)