I think I've got it. The following patch (also posted on
Launchpad) fixes the bug on my system. I am posting it here
for review and testing.

There are two leaks I fixed:

  1. ENDALL_LOOP did not free memory. Now it does.

  2. If you return early from a list using the macro.h macros,
     list memory is not freed. I added an END_LOOP_EARLY macro
     to handle this. However, there are a few problems with
     this approach:

   a. It isn't obvious, especially to new devs, that you
      need to prefix all early returns with this macro.
      Plus, it's ugly.

   b. It only works on 1-level-deep loops. Supporting double-
      or higher nesting will be very difficult with the current
      macro setup.

I dunno what should be done about this. For now, this works
and also drops pcb's increasing memory use for normal work.
(Maybe there are still leaks; I just haven't noticed yet.)
Anyway, this patch will work for now.     



diff --git a/src/macro.h b/src/macro.h
index b61f673..efcec67 100644
--- a/src/macro.h
+++ b/src/macro.h
@@ -175,6 +175,8 @@ extern int mem_any_set (unsigned char *, int);
     g_list_free (__copy);                                           \
   } while (0)
 
+#define END_LOOP_EARLY g_list_free (__copy);
+
 #define STYLE_LOOP(top)  do {                                       \
         GList *__copy = NULL; /* DUMMY */                           \
         Cardinal n;                                                 \
@@ -328,7 +330,11 @@ extern int mem_any_set (unsigned char *, int);
        {                                               \
                point = &(polygon)->Points[n]
 
-#define ENDALL_LOOP }} while (0);  }} while (0)
+#define ENDALL_LOOP }          \
+      g_list_free (__copy);    \
+    } while (0); }             \
+    g_list_free (__copy);      \
+  } while (0)
 
 #define        ALLPIN_LOOP(top)        \
         ELEMENT_LOOP(top); \
@@ -340,6 +346,7 @@ extern int mem_any_set (unsigned char *, int);
 
 #define        ALLLINE_LOOP(top) do    {               \
        Cardinal                l;                      \
+       GList *__copy = NULL; /* DUMMY */               \
        LayerTypePtr    layer = (top)->Layer;           \
        for (l = 0; l < max_copper_layer + 2; l++, layer++)     \
        { \
@@ -347,6 +354,7 @@ extern int mem_any_set (unsigned char *, int);
 
 #define ALLARC_LOOP(top) do {          \
        Cardinal                l;                      \
+       GList *__copy = NULL; /* DUMMY */               \
        LayerTypePtr    layer = (top)->Layer;           \
        for (l =0; l < max_copper_layer + 2; l++, layer++)              \
        { \
@@ -354,6 +362,7 @@ extern int mem_any_set (unsigned char *, int);
 
 #define        ALLPOLYGON_LOOP(top)    do {            \
        Cardinal                l;                      \
+       GList *__copy = NULL; /* DUMMY */               \
        LayerTypePtr    layer = (top)->Layer;           \
        for (l = 0; l < max_copper_layer + 2; l++, layer++)     \
        { \
@@ -361,6 +370,7 @@ extern int mem_any_set (unsigned char *, int);
 
 #define        COPPERLINE_LOOP(top) do {               \
        Cardinal                l;                      \
+       GList *__copy = NULL; /* DUMMY */               \
        LayerTypePtr    layer = (top)->Layer;           \
        for (l = 0; l < max_copper_layer; l++, layer++) \
        { \
@@ -368,6 +378,7 @@ extern int mem_any_set (unsigned char *, int);
 
 #define COPPERARC_LOOP(top) do {               \
        Cardinal                l;                      \
+       GList *__copy = NULL; /* DUMMY */               \
        LayerTypePtr    layer = (top)->Layer;           \
        for (l =0; l < max_copper_layer; l++, layer++)          \
        { \
@@ -375,6 +386,7 @@ extern int mem_any_set (unsigned char *, int);
 
 #define        COPPERPOLYGON_LOOP(top) do      {               \
        Cardinal                l;                      \
+       GList *__copy = NULL; /* DUMMY */               \
        LayerTypePtr    layer = (top)->Layer;           \
        for (l = 0; l < max_copper_layer; l++, layer++) \
        { \
@@ -382,6 +394,7 @@ extern int mem_any_set (unsigned char *, int);
 
 #define        SILKLINE_LOOP(top) do   {               \
        Cardinal                l;                      \
+       GList *__copy = NULL; /* DUMMY */               \
        LayerTypePtr    layer = (top)->Layer;           \
        layer += max_copper_layer;                      \
        for (l = 0; l < 2; l++, layer++)                \
@@ -390,6 +403,7 @@ extern int mem_any_set (unsigned char *, int);
 
 #define SILKARC_LOOP(top) do   {               \
        Cardinal                l;                      \
+       GList *__copy = NULL; /* DUMMY */               \
        LayerTypePtr    layer = (top)->Layer;           \
        layer += max_copper_layer;                      \
        for (l = 0; l < 2; l++, layer++)                \
@@ -398,6 +412,7 @@ extern int mem_any_set (unsigned char *, int);
 
 #define        SILKPOLYGON_LOOP(top) do        {               \
        Cardinal                l;                      \
+       GList *__copy = NULL; /* DUMMY */               \
        LayerTypePtr    layer = (top)->Layer;           \
        layer += max_copper_layer;                      \
        for (l = 0; l < 2; l++, layer++)                \
@@ -406,6 +421,7 @@ extern int mem_any_set (unsigned char *, int);
 
 #define        ALLTEXT_LOOP(top)       do {            \
        Cardinal                l;                      \
+       GList *__copy = NULL; /* DUMMY */               \
        LayerTypePtr    layer = (top)->Layer;           \
        for (l = 0; l < max_copper_layer + 2; l++, layer++)     \
        { \
@@ -413,6 +429,7 @@ extern int mem_any_set (unsigned char *, int);
 
 #define        VISIBLELINE_LOOP(top) do        {               \
        Cardinal                l;                      \
+       GList *__copy = NULL; /* DUMMY */               \
        LayerTypePtr    layer = (top)->Layer;           \
        for (l = 0; l < max_copper_layer + 2; l++, layer++)     \
        { \
@@ -421,6 +438,7 @@ extern int mem_any_set (unsigned char *, int);
 
 #define        VISIBLEARC_LOOP(top) do {               \
        Cardinal                l;                      \
+       GList *__copy = NULL; /* DUMMY */               \
        LayerTypePtr    layer = (top)->Layer;           \
        for (l = 0; l < max_copper_layer + 2; l++, layer++)     \
        { \
@@ -429,6 +447,7 @@ extern int mem_any_set (unsigned char *, int);
 
 #define        VISIBLETEXT_LOOP(board) do      {               \
        Cardinal                l;                      \
+       GList *__copy = NULL; /* DUMMY */               \
        LayerTypePtr    layer = (board)->Data->Layer;           \
        for (l = 0; l < max_copper_layer + 2; l++, layer++)     \
        { \
@@ -437,6 +456,7 @@ extern int mem_any_set (unsigned char *, int);
 
 #define        VISIBLEPOLYGON_LOOP(top) do     {       \
        Cardinal                l;                      \
+       GList *__copy = NULL; /* DUMMY */               \
        LayerTypePtr    layer = (top)->Layer;           \
        for (l = 0; l < max_copper_layer + 2; l++, layer++)     \
        { \
diff --git a/src/search.c b/src/search.c
index 30fe883..b50f3cb 100644
--- a/src/search.c
+++ b/src/search.c
@@ -1383,6 +1383,7 @@ SearchObjectByID (DataTypePtr Base,
          {
            *Result1 = (void *) layer;
            *Result2 = *Result3 = (void *) line;
+           END_LOOP_EARLY;
            return (LINE_TYPE);
          }
        if (line->Point1.ID == ID)
@@ -1390,6 +1391,7 @@ SearchObjectByID (DataTypePtr Base,
            *Result1 = (void *) layer;
            *Result2 = (void *) line;
            *Result3 = (void *) &line->Point1;
+           END_LOOP_EARLY;
            return (LINEPOINT_TYPE);
          }
        if (line->Point2.ID == ID)
@@ -1397,6 +1399,7 @@ SearchObjectByID (DataTypePtr Base,
            *Result1 = (void *) layer;
            *Result2 = (void *) line;
            *Result3 = (void *) &line->Point2;
+           END_LOOP_EARLY;
            return (LINEPOINT_TYPE);
          }
       }
@@ -1410,6 +1413,7 @@ SearchObjectByID (DataTypePtr Base,
          {
            *Result1 = (void *) layer;
            *Result2 = *Result3 = (void *) arc;
+           END_LOOP_EARLY;
            return (ARC_TYPE);
          }
       }
@@ -1424,6 +1428,7 @@ SearchObjectByID (DataTypePtr Base,
          {
            *Result1 = (void *) layer;
            *Result2 = *Result3 = (void *) text;
+           END_LOOP_EARLY;
            return (TEXT_TYPE);
          }
       }
@@ -1438,6 +1443,7 @@ SearchObjectByID (DataTypePtr Base,
          {
            *Result1 = (void *) layer;
            *Result2 = *Result3 = (void *) polygon;
+           END_LOOP_EARLY;
            return (POLYGON_TYPE);
          }
        if (type == POLYGONPOINT_TYPE)
@@ -1448,6 +1454,7 @@ SearchObjectByID (DataTypePtr Base,
              *Result1 = (void *) layer;
              *Result2 = (void *) polygon;
              *Result3 = (void *) point;
+             END_LOOP_EARLY;
              return (POLYGONPOINT_TYPE);
            }
        }
@@ -1462,6 +1469,7 @@ SearchObjectByID (DataTypePtr Base,
        if (via->ID == ID)
          {
            *Result1 = *Result2 = *Result3 = (void *) via;
+           END_LOOP_EARLY;
            return (VIA_TYPE);
          }
       }
@@ -1475,6 +1483,7 @@ SearchObjectByID (DataTypePtr Base,
        if (line->ID == ID)
          {
            *Result1 = *Result2 = *Result3 = (void *) line;
+           END_LOOP_EARLY;
            return (RATLINE_TYPE);
          }
        if (line->Point1.ID == ID)
@@ -1482,6 +1491,7 @@ SearchObjectByID (DataTypePtr Base,
            *Result1 = (void *) NULL;
            *Result2 = (void *) line;
            *Result3 = (void *) &line->Point1;
+           END_LOOP_EARLY;
            return (LINEPOINT_TYPE);
          }
        if (line->Point2.ID == ID)
@@ -1489,6 +1499,7 @@ SearchObjectByID (DataTypePtr Base,
            *Result1 = (void *) NULL;
            *Result2 = (void *) line;
            *Result3 = (void *) &line->Point2;
+           END_LOOP_EARLY;
            return (LINEPOINT_TYPE);
          }
       }
@@ -1504,6 +1515,7 @@ SearchObjectByID (DataTypePtr Base,
     if (element->ID == ID)
       {
        *Result1 = *Result2 = *Result3 = (void *) element;
+        END_LOOP_EARLY;
        return (ELEMENT_TYPE);
       }
     if (type == ELEMENTLINE_TYPE)
@@ -1513,6 +1525,7 @@ SearchObjectByID (DataTypePtr Base,
        {
          *Result1 = (void *) element;
          *Result2 = *Result3 = (void *) line;
+          END_LOOP_EARLY;
          return (ELEMENTLINE_TYPE);
        }
     }
@@ -1524,6 +1537,7 @@ SearchObjectByID (DataTypePtr Base,
        {
          *Result1 = (void *) element;
          *Result2 = *Result3 = (void *) arc;
+          END_LOOP_EARLY;
          return (ELEMENTARC_TYPE);
        }
     }
@@ -1535,6 +1549,7 @@ SearchObjectByID (DataTypePtr Base,
        {
          *Result1 = (void *) element;
          *Result2 = *Result3 = (void *) text;
+          END_LOOP_EARLY;
          return (ELEMENTNAME_TYPE);
        }
     }
@@ -1546,6 +1561,7 @@ SearchObjectByID (DataTypePtr Base,
        {
          *Result1 = (void *) element;
          *Result2 = *Result3 = (void *) pin;
+          END_LOOP_EARLY;
          return (PIN_TYPE);
        }
     }
@@ -1557,6 +1573,7 @@ SearchObjectByID (DataTypePtr Base,
        {
          *Result1 = (void *) element;
          *Result2 = *Result3 = (void *) pad;
+          END_LOOP_EARLY;
          return (PAD_TYPE);
        }
     }
@@ -1583,6 +1600,7 @@ SearchElementByName (DataTypePtr Base, char *Name)
        NSTRCMP (element->Name[1].TextString, Name) == 0)
       {
        result = element;
+       END_LOOP_EARLY;
        return (result);
       }
   }



_______________________________________________
geda-user mailing list
geda-user@moria.seul.org
http://www.seul.org/cgi-bin/mailman/listinfo/geda-user

Reply via email to