try to make vips_thread_shutdown() optional

see

https://github.com/jcupitt/ruby-vips/issues/55

it's still better to call vips_thread_shutdown(), but not calling it
should no longer leak memory
This commit is contained in:
John Cupitt 2014-09-30 11:28:24 +01:00
parent b1827128ea
commit cad052544c
3 changed files with 14 additions and 30 deletions

View File

@ -1,6 +1,7 @@
8/9/14 started 7.40.10 8/9/14 started 7.40.10
- icc_import and icc_transform checks the input profile for compatibility - icc_import and icc_transform checks the input profile for compatibility
with the image, thanks James with the image, thanks James
- try to make vips_thread_shutdown() optional
8/9/14 started 7.40.9 8/9/14 started 7.40.9
- support jfif resunit "none" - support jfif resunit "none"

View File

@ -582,24 +582,12 @@ vips_buffer_print( VipsBuffer *buffer )
static void static void
vips__buffer_init_cb( VipsBufferThread *buffer_thread ) vips__buffer_init_cb( VipsBufferThread *buffer_thread )
{ {
/* This is a mem leak, not catastrophic. /* We only come here if vips_thread_shutdown() was not called for this
*/ * thread. Do our best to clean up.
/* Threads (including the main thread) must call
* vips_thread_shutdown() before exiting. Check that they have.
* *
* We can't save automatically, because the shutdown order is * GPrivate has stopped working, be careful not to touch that.
* important. We must free all memory before saving the thread
* profile, for example.
*
* We can't do the freeing in this callback since GPrivate has already
* stopped working.
*/ */
buffer_thread_free( buffer_thread );
vips_warn( "VipsBuffer",
_( "vips_thread_shutdown() not called for thread %p, see %s" ),
g_thread_self(),
"https://github.com/jcupitt/ruby-vips/issues/55" );
} }
/* Init the buffer cache system. /* Init the buffer cache system.

View File

@ -166,9 +166,6 @@ vips_thread_profile_free( VipsThreadProfile *profile )
{ {
VIPS_DEBUG_MSG( "vips_thread_profile_free: %s\n", profile->name ); VIPS_DEBUG_MSG( "vips_thread_profile_free: %s\n", profile->name );
if( vips__thread_profile )
vips_thread_profile_save( profile );
VIPS_FREEF( g_hash_table_destroy, profile->gates ); VIPS_FREEF( g_hash_table_destroy, profile->gates );
VIPS_FREEF( vips_thread_gate_free, profile->memory ); VIPS_FREEF( vips_thread_gate_free, profile->memory );
VIPS_FREE( profile ); VIPS_FREE( profile );
@ -183,20 +180,15 @@ vips__thread_profile_stop( void )
static void static void
vips__thread_profile_init_cb( VipsThreadProfile *profile ) vips__thread_profile_init_cb( VipsThreadProfile *profile )
{ {
/* Threads (including the main thread) must call /* We only come here if vips_thread_shutdown() was not called for this
* vips_thread_shutdown() before exiting. Check that they have. * thread. Do our best to clean up.
* *
* We can't save automatically, because the shutdown order is * GPrivate has stopped working, be careful not to touch that.
* important. We must free all memory before saving the thread
* profile, for example.
* *
* We can't do the freeing in this callback since GPrivate has already * Don't try to save: this is an emergency recovery path.
* stopped working.
*/ */
vips_warn( "VipsBuffer", vips_thread_profile_free( profile );
_( "vips_thread_shutdown() not called for thread %p" ),
g_thread_self() );
} }
static void static void
@ -269,6 +261,9 @@ vips__thread_profile_detach( void )
VIPS_DEBUG_MSG( "vips__thread_profile_detach:\n" ); VIPS_DEBUG_MSG( "vips__thread_profile_detach:\n" );
if( (profile = vips_thread_profile_get()) ) { if( (profile = vips_thread_profile_get()) ) {
if( vips__thread_profile )
vips_thread_profile_save( profile );
vips_thread_profile_free( profile ); vips_thread_profile_free( profile );
g_private_set( vips_thread_profile_key, NULL ); g_private_set( vips_thread_profile_key, NULL );
} }