From 1273dbd57ada42420cecf961599e74661e0c7066 Mon Sep 17 00:00:00 2001
From: Robin Watts <robin.watts@artifex.com>
Date: Mon, 28 Mar 2016 13:13:31 +0100
Subject: Memento: Add facility to cope with 'known' leaked blocks.

Harfbuzz allocates blocks that it keeps around as statics.
There are a finite number of these, and they are never freed
(at least not in the build we use). Having Memento report
them as leaks is a pain.

So we extend Memento so that we can label blocks as being
leaks, and thus never have to be bothered by them.
---
 include/mupdf/memento.h |  5 +++++
 source/fitz/memento.c   | 44 ++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 47 insertions(+), 2 deletions(-)

diff --git a/include/mupdf/memento.h b/include/mupdf/memento.h
index e2ea3562..b6d2c8f7 100644
--- a/include/mupdf/memento.h
+++ b/include/mupdf/memento.h
@@ -226,6 +226,9 @@ void *Memento_takeRef(void *blk);
 void *Memento_dropRef(void *blk);
 void *Memento_reference(void *blk);
 
+void Memento_startLeaking(void);
+void Memento_stopLeaking(void);
+
 #ifdef MEMENTO
 
 #ifndef COMPILING_MEMENTO_C
@@ -265,6 +268,8 @@ void *Memento_reference(void *blk);
 #define Memento_takeRef(A)        (A)
 #define Memento_dropRef(A)        (A)
 #define Memento_reference(A)      (A)
+#define Memento_startLeaking()    do {} while (0)
+#define Memento_stopLeaking()     do {} while (0)
 
 #endif /* MEMENTO */
 
diff --git a/source/fitz/memento.c b/source/fitz/memento.c
index 36693366..abb9f427 100644
--- a/source/fitz/memento.c
+++ b/source/fitz/memento.c
@@ -171,7 +171,8 @@ enum {
     Memento_Flag_HasParent = 2,
     Memento_Flag_BreakOnFree = 4,
     Memento_Flag_BreakOnRealloc = 8,
-    Memento_Flag_Freed = 16
+    Memento_Flag_Freed = 16,
+    Memento_Flag_KnownLeak = 32
 };
 
 enum {
@@ -294,6 +295,7 @@ static struct {
     int            pattern;
     int            nextPattern;
     int            patternBit;
+    int            leaking;
     size_t         maxMemory;
     size_t         alloc;
     size_t         peakAlloc;
@@ -1013,6 +1015,8 @@ static void showBlock(Memento_BlkHeader *b, int space)
             MEMBLK_TOBLK(b), (int)b->rawsize, b->sequence);
     if (b->label)
         fprintf(stderr, "%c(%s)", space, b->label);
+    if (b->flags & Memento_Flag_KnownLeak)
+        fprintf(stderr, "(Known Leak)");
 }
 
 static void blockDisplay(Memento_BlkHeader *b, int n)
@@ -1262,11 +1266,23 @@ void Memento_listBlockInfo(void)
 #endif
 }
 
+static int Memento_nonLeakBlocksLeaked(void)
+{
+	Memento_BlkHeader *blk = memento.used.head;
+	while (blk)
+	{
+		if ((blk->flags & Memento_Flag_KnownLeak) == 0)
+			return 1;
+		blk = blk->next;
+	}
+	return 0;
+}
+
 static void Memento_fin(void)
 {
     Memento_checkAllMemory();
     Memento_endStats();
-    if (memento.used.head != NULL) {
+    if (Memento_nonLeakBlocksLeaked()) {
         Memento_listBlocks();
 #ifdef MEMENTO_DETAILS
         fprintf(stderr, "\n");
@@ -1682,6 +1698,10 @@ static void *do_malloc(size_t s, int eventType)
     Memento_storeDetails(memblk, Memento_EventType_malloc);
 #endif /* MEMENTO_DETAILS */
     Memento_addBlockHead(&memento.used, memblk, 0);
+
+    if (memento.leaking > 0)
+	    memblk->flags |= Memento_Flag_KnownLeak;
+
     return MEMBLK_TOBLK(memblk);
 }
 
@@ -2182,6 +2202,18 @@ size_t Memento_setMax(size_t max)
     memento.maxMemory = max;
     return max;
 }
+
+void Memento_startLeaking(void)
+{
+	memento.leaking++;
+}
+
+void Memento_stopLeaking(void)
+{
+	memento.leaking--;
+}
+
+
 #endif /* MEMENTO_CPP_EXTRAS_ONLY */
 
 #ifdef __cplusplus
@@ -2346,4 +2378,12 @@ void (Memento_listBlockInfo)(void)
 {
 }
 
+void (Memento_startLeaking)(void)
+{
+}
+
+void (Memento_stopLeaking)(void)
+{
+}
+
 #endif
-- 
cgit v1.2.3