diff --git a/ChangeLog b/ChangeLog index 2dac665b..b87946ce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,8 @@ 18/10/16 started 8.4.3 - fix error detection in gif_close, thanks aaron42net +- fix tiny threading memleak +- improve compatibility with very old glib, see #548 27/9/16 started 8.4.2 - small doc improvements diff --git a/libvips/conversion/bandbool.c b/libvips/conversion/bandbool.c index 86385048..d26c5d7d 100644 --- a/libvips/conversion/bandbool.c +++ b/libvips/conversion/bandbool.c @@ -186,7 +186,7 @@ vips_bandbool_buffer( VipsBandary *bandary, #define D VIPS_FORMAT_DOUBLE #define DX VIPS_FORMAT_DPCOMPLEX -/* Type conversions for boolean. +/* Format conversions for boolean. */ static const VipsBandFormat vips_bandbool_format_table[10] = { /* UC C US S UI I F X D DX */ diff --git a/libvips/include/vips/internal.h b/libvips/include/vips/internal.h index e88f1eb3..1fa940a1 100644 --- a/libvips/include/vips/internal.h +++ b/libvips/include/vips/internal.h @@ -104,6 +104,8 @@ extern gboolean vips__cache_trace; extern int vips__n_active_threads; +void vips__threadpool_init( void ); + void vips__cache_init( void ); void vips__print_renders( void ); diff --git a/libvips/iofuncs/buffer.c b/libvips/iofuncs/buffer.c index e315b5ce..8338468e 100644 --- a/libvips/iofuncs/buffer.c +++ b/libvips/iofuncs/buffer.c @@ -652,7 +652,7 @@ buffer_thread_destroy_notify( VipsBufferThread *buffer_thread ) buffer_thread_free( buffer_thread ); } -/* Init the buffer cache system. This must only be called from worker threads. +/* Init the buffer cache system. This is called during vips_init. */ void vips__buffer_init( void ) diff --git a/libvips/iofuncs/init.c b/libvips/iofuncs/init.c index a0ea934e..5650be42 100644 --- a/libvips/iofuncs/init.c +++ b/libvips/iofuncs/init.c @@ -302,6 +302,9 @@ vips_init( const char *argv0 ) g_thread_init( NULL ); #endif + vips__threadpool_init(); + vips__buffer_init(); + /* This does an unsynchronised static hash table init on first call -- * we have to make sure we do this single-threaded. See: * https://github.com/openslide/openslide/issues/161 diff --git a/libvips/iofuncs/threadpool.c b/libvips/iofuncs/threadpool.c index 7592bd9c..577309dd 100644 --- a/libvips/iofuncs/threadpool.c +++ b/libvips/iofuncs/threadpool.c @@ -106,7 +106,7 @@ int vips__n_active_threads = 0; /* Set this GPrivate to indicate that this is a vips worker. */ -static GPrivate vips_threadpool_is_worker_private; +static GPrivate *is_worker_key = NULL; /* Glib 2.32 revised the thread API. We need some compat functions. */ @@ -170,7 +170,7 @@ vips_g_cond_free( GCond *cond ) gboolean vips_thread_isworker( void ) { - return( g_private_get( &vips_threadpool_is_worker_private ) != NULL ); + return( g_private_get( is_worker_key ) != NULL ); } typedef struct { @@ -188,7 +188,10 @@ vips_thread_run( gpointer data ) /* Set this to something (anything) to tag this thread as a vips worker. */ - g_private_set( &vips_threadpool_is_worker_private, data ); + g_private_set( is_worker_key, data ); + + if( vips__thread_profile ) + vips__thread_profile_attach( info->domain ); if( vips__thread_profile ) vips__thread_profile_attach( info->domain ); @@ -996,6 +999,23 @@ vips_threadpool_run( VipsImage *im, return( result ); } +/* Start up threadpools. This is called during vips_init. + */ +void +vips__threadpool_init( void ) +{ + /* We need to work with the pre-2.32 threading API. + */ +#ifdef HAVE_PRIVATE_INIT + static GPrivate private = { 0 }; + + is_worker_key = &private; +#else + if( !is_worker_key ) + is_worker_key = g_private_new( NULL ); +#endif +} + /** * vips_get_tile_size: * @im: image to guess for diff --git a/test/test_foreign.py b/test/test_foreign.py index 5698793c..c6d0eba0 100755 --- a/test/test_foreign.py +++ b/test/test_foreign.py @@ -58,9 +58,13 @@ class TestForeign(unittest.TestCase): self.colour = Vips.Image.jpegload(self.jpeg_file) self.mono = self.colour.extract_band(1) + # we remove the ICC profile: the RGB one will no longer be appropriate + self.mono.remove("icc-profile-data") self.rad = self.colour.float2rad() + self.rad.remove("icc-profile-data") self.cmyk = self.colour.bandjoin(self.mono) self.cmyk = self.cmyk.copy(interpretation = Vips.Interpretation.CMYK) + self.cmyk.remove("icc-profile-data") im = Vips.Image.new_from_file(self.gif_file) self.onebit = im > 128