make VipsArea threadsafe

google maps output needs threaded create / destroy of VipsArea (used to
hold the background colour). We need a lock on VipsArea::count.

Fixes https://github.com/jcupitt/libvips/issues/46

Thanks fuho
This commit is contained in:
John Cupitt 2012-12-19 09:58:35 +00:00
parent c3a9f9cda5
commit 8b67d53e56
4 changed files with 30 additions and 4 deletions

View File

@ -32,6 +32,7 @@
- added vips_bandbool(), with vips_bandand(), _bandor(), _bandeor() as
convenience functions
- added scRGB colourspace, linear light float space with sRGB primaries
- VipsArea is threadsafe
14/11/12 started 7.30.6
- capture tiff warnings earlier

View File

@ -1046,6 +1046,17 @@ vips_foreign_save_dz_build( VipsObject *object )
VIPS_SETSTR( dz->suffix, ".jpg" );
}
/* Default to white background.
*/
if( dz->layout == VIPS_FOREIGN_DZ_LAYOUT_GOOGLE &&
!vips_object_argument_isset( object, "background" ) ) {
VipsArrayDouble *background;
background = vips_array_double_newv( 1, 255.0 );
g_object_set( object, "background", background, NULL );
vips_area_unref( background );
}
if( dz->overlap >= dz->tile_size ||
dz->overlap >= dz->tile_size ) {
vips_error( "dzsave",
@ -1231,9 +1242,6 @@ vips_foreign_save_dz_init( VipsForeignSaveDz *dz )
dz->overlap = 1;
dz->tile_size = 256;
dz->tile_count = 0;
dz->background =
vips_area_new_array( G_TYPE_DOUBLE, sizeof( double ), 1 );
((double *) (dz->background->data))[0] = 255;
dz->depth = VIPS_FOREIGN_DZ_DEPTH_1PIXEL;
}

View File

@ -66,9 +66,13 @@ typedef struct _VipsArea {
/*< private >*/
/* Reference count.
/* Reference count and lock.
*
* We could use an atomic int, but this is not a high-traffic data
* structure, so a simple GMutex is OK.
*/
int count;
GMutex *lock;
/* Things like ICC profiles need their own free functions.
*/

View File

@ -147,6 +147,8 @@ static int vips_area_number = 0;
VipsArea *
vips_area_copy( VipsArea *area )
{
g_mutex_lock( area->lock );
g_assert( area->count >= 0 );
area->count += 1;
@ -155,12 +157,16 @@ vips_area_copy( VipsArea *area )
printf( "vips_area_copy: %p count = %d\n", area, area->count );
#endif /*DEBUG*/
g_mutex_unlock( area->lock );
return( area );
}
void
vips_area_unref( VipsArea *area )
{
g_mutex_lock( area->lock );
g_assert( area->count > 0 );
area->count -= 1;
@ -176,6 +182,10 @@ vips_area_unref( VipsArea *area )
area->free_fn = NULL;
}
g_mutex_unlock( area->lock );
VIPS_FREEF( vips_g_mutex_free, area->lock );
g_free( area );
#ifdef DEBUG
@ -184,6 +194,8 @@ vips_area_unref( VipsArea *area )
vips_area_number );
#endif /*DEBUG*/
}
else
g_mutex_unlock( area->lock );
}
/**
@ -205,6 +217,7 @@ vips_area_new( VipsCallbackFn free_fn, void *data )
area = g_new( VipsArea, 1 );
area->count = 1;
area->lock = vips_g_mutex_new();
area->length = 0;
area->data = data;
area->free_fn = free_fn;