[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
Re: gEDA-user: PCB head fails with ***MEMORY-ERROR***
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@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-user