better type leak checks

This commit is contained in:
John Cupitt 2013-08-06 12:02:11 +01:00
parent 02095763c9
commit ba60202285
4 changed files with 54 additions and 10 deletions

View File

@ -75,6 +75,10 @@ extern int vips__fatal;
*/
extern int vips__progress;
/* Leak check on exit.
*/
extern int vips__leak;
/* A string giving the image size (in bytes of uncompressed image) above which
* we decompress to disc on open.
*/

View File

@ -91,6 +91,7 @@ typedef struct _VipsArea {
VipsArea *vips_area_copy( VipsArea *area );
void vips_area_unref( VipsArea *area );
void vips__type_leak( void );
VipsArea *vips_area_new( VipsCallbackFn free_fn, void *data );
VipsArea *vips_area_new_blob( VipsCallbackFn free_fn,

View File

@ -96,7 +96,7 @@ static char *vips__argv0 = NULL;
/* Leak check on exit.
*/
static int vips__leak = 0;
int vips__leak = 0;
/**
* vips_get_argv0:
@ -327,6 +327,8 @@ vips_leak( void )
vips_buf_appends( &buf, "\n" );
fprintf( stderr, "%s", vips_buf_all( &buf ) );
vips__type_leak();
}
/**

View File

@ -5,6 +5,8 @@
*
* 27/10/11
* - from header.c
* 16/7/13
* - leakcheck VipsArea
*/
/*
@ -35,9 +37,9 @@
*/
/*
*/
#define VIPS_DEBUG
#define DEBUG
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
@ -141,16 +143,14 @@ vips_thing_get_type( void )
* strings.
*/
#ifdef DEBUG
static int vips_area_number = 0;
#endif /*DEBUG*/
static GSList *vips_area_all = NULL;
VipsArea *
vips_area_copy( VipsArea *area )
{
g_mutex_lock( area->lock );
g_assert( area->count >= 0 );
g_assert( area->count > 0 );
area->count += 1;
@ -176,6 +176,12 @@ vips_area_unref( VipsArea *area )
printf( "vips_area_unref: %p count = %d\n", area, area->count );
#endif /*DEBUG*/
if( vips__leak ) {
g_mutex_lock( vips__global_lock );
g_assert( g_slist_find( vips_area_all, area ) );
g_mutex_unlock( vips__global_lock );
}
if( area->count == 0 ) {
if( area->free_fn && area->data ) {
area->free_fn( area->data, area );
@ -189,10 +195,17 @@ vips_area_unref( VipsArea *area )
g_free( area );
if( vips__leak ) {
g_mutex_lock( vips__global_lock );
vips_area_all = g_slist_remove( vips_area_all, area );
g_mutex_unlock( vips__global_lock );
}
#ifdef DEBUG
vips_area_number -= 1;
g_mutex_lock( vips__global_lock );
printf( "vips_area_unref: free .. total = %d\n",
vips_area_number );
g_slist_length( vips_area_all ) );
g_mutex_unlock( vips__global_lock );
#endif /*DEBUG*/
}
else
@ -225,15 +238,39 @@ vips_area_new( VipsCallbackFn free_fn, void *data )
area->type = 0;
area->sizeof_type = 0;
if( vips__leak ) {
g_mutex_lock( vips__global_lock );
vips_area_all = g_slist_prepend( vips_area_all, area );
g_mutex_unlock( vips__global_lock );
}
#ifdef DEBUG
vips_area_number += 1;
g_mutex_lock( vips__global_lock );
printf( "vips_area_new: %p count = %d (%d in total)\n",
area, area->count, vips_area_number );
area, area->count,
g_slist_length( vips_area_all ) );
g_mutex_unlock( vips__global_lock );
#endif /*DEBUG*/
return( area );
}
void
vips__type_leak( void )
{
if( vips_area_all ) {
GSList *p;
printf( "VipsArea leaks:\n" );
for( p = vips_area_all; p; p = p->next ) {
VipsArea *area = (VipsArea *) p->data;
printf( "\t%p count = %d\n", area, area->count );
}
printf( "%d in total\n", g_slist_length( vips_area_all ) );
}
}
/**
* vips_area_new_blob:
* @free_fn: (scope async): @data will be freed with this function