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:
parent
c3a9f9cda5
commit
8b67d53e56
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user