[babl] Add a babl_set_destructor
- From: Øyvind Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [babl] Add a babl_set_destructor
- Date: Sat, 26 Jun 2010 03:05:38 +0000 (UTC)
commit c435986318527b8dba3265d963b0e45fedb0d18b
Author: �yvind Kolås <pippin gimp org>
Date: Sat Jun 26 03:54:53 2010 +0100
Add a babl_set_destructor
Keep a callback function for each allocation instance, that allows an
allocation specific callback to be called when the memory segment is
freed. This makes a valgrind warning go away, most of the time no extra
memory should be needed since this is likely to fit within the padding.
babl/babl-format.c | 14 +++++++++++
babl/babl-image.c | 12 +++++++++
babl/babl-memory.c | 66 ++++++++++++++-------------------------------------
babl/babl-memory.h | 40 ++++++++++++++++---------------
4 files changed, 65 insertions(+), 67 deletions(-)
---
diff --git a/babl/babl-format.c b/babl/babl-format.c
index 8494d9f..227dab0 100644
--- a/babl/babl-format.c
+++ b/babl/babl-format.c
@@ -24,6 +24,19 @@
#include "babl-internal.h"
#include "babl-db.h"
+static int babl_format_destruct (void *babl)
+{
+ BablFormat *format = babl;
+ if (format->image_template != NULL)
+ {
+ babl_set_destructor (format->image_template, NULL);
+ /* with no destructor set, the circular reference is no problem */
+ babl_free (format->image_template);
+ format->image_template = NULL;
+ }
+ return 0;
+}
+
static int
each_babl_format_destroy (Babl *babl,
void *data)
@@ -75,6 +88,7 @@ format_new (const char *name,
sizeof (BablType *) * (components) +
sizeof (int) * (components) +
sizeof (int) * (components));
+ babl_set_destructor (babl, babl_format_destruct);
babl->format.from_list = NULL;
babl->format.component = (void *) (((char *) babl) + sizeof (BablFormat));
diff --git a/babl/babl-image.c b/babl/babl-image.c
index f54c87e..ed28c89 100644
--- a/babl/babl-image.c
+++ b/babl/babl-image.c
@@ -22,6 +22,17 @@
#include "babl-internal.h"
+static int babl_image_destruct (void *babl)
+{
+ BablFormat *format = BABL (babl)->image.format;
+ if (format && format->image_template == NULL)
+ {
+ format->image_template = babl;
+ return -1; /* this should avoid freeing images created for formats,. */
+ }
+ return 0;
+}
+
static Babl *
image_new (BablFormat *format,
BablModel *model,
@@ -43,6 +54,7 @@ image_new (BablFormat *format,
sizeof (void*) * (components) +
sizeof (int) * (components) +
sizeof (int) * (components));
+ babl_set_destructor (babl, babl_image_destruct);
babl->image.component = (void*)(((char *)babl) + sizeof (BablImage));
babl->image.sampling = (void*)(((char *)babl->image.component) + sizeof (BablComponent*) * (components));
babl->image.type = (void*)(((char *)babl->image.sampling) + sizeof (BablSampling*) * (components));
diff --git a/babl/babl-memory.c b/babl/babl-memory.c
index b228447..df837a3 100644
--- a/babl/babl-memory.c
+++ b/babl/babl-memory.c
@@ -47,6 +47,7 @@ typedef struct
{
char *signature;
size_t size;
+ int (*destructor)(void *ptr);
} BablAllocInfo;
#define BABL_ALIGN 16
@@ -117,6 +118,7 @@ babl_malloc (size_t size)
*((void **) ret - 1) = ret - BABL_ALLOC - offset;
BAI (ret)->signature = signature;
BAI (ret)->size = size;
+ BAI (ret)->destructor = NULL;
#if BABL_DEBUG_MEM
babl_mutex_lock (babl_debug_mutex);
mallocs++;
@@ -125,6 +127,16 @@ babl_malloc (size_t size)
return (void *) (ret);
}
+/* set a callback to be called when the segment is freed.
+ */
+void
+babl_set_destructor (void *ptr,
+ int (*destructor)(void *ptr))
+{
+ babl_assert (IS_BAI (ptr));
+ BAI(ptr)->destructor = destructor;
+}
+
/* Create a duplicate allocation of the same size, note
* that the exact location of the allocation needs to be
* passed.
@@ -158,58 +170,16 @@ void
babl_free (void *ptr,
...)
{
- /* XXX:
- * Extra logic to make the bookeeping of BablImage cached
- * templates work out correctly, by using a babl_image_destroy
- * and custom destroy functions for babl_format this would be
- * avoided and the extra overhead not needed for non image/format
- * typed allocations.
- */
- if (BABL_IS_BABL (ptr))
- {
- switch (BABL (ptr)->instance.class_type)
- {
- case BABL_IMAGE:
- {
- BablFormat *format = BABL(ptr)->image.format;
- if (format)
- {
- if (format->image_template == NULL)
- {
- format->image_template = ptr;
- return;
- }
- else
- {
- }
- }
- }
- break;
- case BABL_FORMAT:
- {
- BablFormat *format = ptr;
- if (format->image_template != NULL)
- {
- BAI (format->image_template)->signature = NULL;
- free_f (BAI (format->image_template));
-#if BABL_DEBUG_MEM
- babl_mutex_lock (babl_debug_mutex);
- frees++;
- babl_mutex_unlock (babl_debug_mutex);
-#endif
- }
- format->image_template = NULL;
- }
- break;
- default:
- break;
- }
- }
+ functions_sanity ();
if (!ptr)
return;
if (!IS_BAI (ptr))
babl_fatal ("memory not allocated by babl allocator");
- functions_sanity ();
+
+ if (BAI (ptr)->destructor)
+ if (BAI (ptr)->destructor (ptr))
+ return; /* bail out on non 0 return from destructor */
+
BAI (ptr)->signature = NULL;
free_f (BAI (ptr));
#if BABL_DEBUG_MEM
diff --git a/babl/babl-memory.h b/babl/babl-memory.h
index b4e0d81..251f0c3 100644
--- a/babl/babl-memory.h
+++ b/babl/babl-memory.h
@@ -24,24 +24,26 @@ typedef void * (* BablMallocFunc) (size_t size);
typedef void (* BablFreeFunc) (void *ptr);
-void babl_set_malloc (BablMallocFunc malloc_function);
-void babl_set_free (BablFreeFunc free_function);
-int babl_memory_sanity (void);
-
-void * babl_malloc (size_t size);
-void babl_free (void *ptr,
- ...);
-void * babl_calloc (size_t nmemb,
- size_t size);
-void * babl_realloc (void *ptr,
- size_t size);
-
-size_t babl_sizeof (void *ptr);
-void * babl_dup (void *ptr);
-
-char * babl_strdup (const char *s);
-char * babl_strcat (char *dest,
- const char *src);
-
+void babl_set_malloc (BablMallocFunc malloc_function);
+void babl_set_free (BablFreeFunc free_function);
+int babl_memory_sanity (void);
+
+void * babl_malloc (size_t size);
+void babl_set_destructor (void *ptr,
+ int (*destructor)(void *ptr));
+
+void babl_free (void *ptr,
+ ...);
+void * babl_calloc (size_t nmemb,
+ size_t size);
+void * babl_realloc (void *ptr,
+ size_t size);
+
+size_t babl_sizeof (void *ptr);
+void * babl_dup (void *ptr);
+
+char * babl_strdup (const char *s);
+char * babl_strcat (char *dest,
+ const char *src);
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]