diff --git a/ChangeLog b/ChangeLog index 67bce88a..2689e59d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,8 @@ - openslide2vips gets underlying tile size from openslide - embed has 'background' option - dzsave --layout google has a @background option +- use vips_mutex_new()/_free() over g_mutex_new()/_free() +- remove no threads option 2/10/12 started 7.30.4 - remove options from format string in .dzi (thanks Martin) diff --git a/configure.in b/configure.in index 4e631242..184df20a 100644 --- a/configure.in +++ b/configure.in @@ -318,16 +318,10 @@ AC_CHECK_LIB(m,hypot,[AC_DEFINE(HAVE_HYPOT,1,[have hypot() in libm.])]) PKG_CHECK_MODULES(REQUIRED, glib-2.0 >= 2.6 gmodule-2.0 >= 2.4 libxml-2.0 gobject-2.0) PACKAGES_USED="$PACKAGES_USED glib-2.0 gmodule-2.0 libxml-2.0 gobject-2.0" -# option to eval without threads -AC_ARG_ENABLE(threads, - AS_HELP_STRING([--enable-threads], [evaluate with threads (default: yes)])) - -if test x"$enable_threads" != "xno"; then - AC_DEFINE(HAVE_THREADS,1,[threaded evaluation]) - PKG_CHECK_MODULES(GTHREAD, gthread-2.0) - PACKAGES_USED="$PACKAGES_USED gthread-2.0" - enable_threads=yes -fi +# after 2.32 g_mutex_new() becomes g_mutex_init(), annoyingly +PKG_CHECK_MODULES(THREADS, glib-2.0 >= 2.32,[ + AC_DEFINE(HAVE_MUTEX_INIT,1,[define if your glib has g_mutex_init().]) +]) # check for gtk-doc GTK_DOC_CHECK(1.9) @@ -734,7 +728,6 @@ native win32: $vips_os_win32 native OS X: $vips_os_darwin open files in binary mode: $vips_binary_open enable debug: $enable_debug -evaluate with threads: $enable_threads build C++ components: $enable_cxx build docs with gtkdoc: $enable_gtk_doc gobject introspection: $found_introspection diff --git a/libvips/colour/im_icc_transform.c b/libvips/colour/im_icc_transform.c index 04f765d7..88255b03 100644 --- a/libvips/colour/im_icc_transform.c +++ b/libvips/colour/im_icc_transform.c @@ -147,7 +147,7 @@ icc_destroy( Icc *icc ) IM_FREEF( cmsDeleteTransform, icc->trans ); IM_FREEF( cmsCloseProfile, icc->in_profile ); IM_FREEF( cmsCloseProfile, icc->out_profile ); - IM_FREEF( g_mutex_free, icc->lock ); + IM_FREEF( vips_mutex_free, icc->lock ); return( 0 ); } @@ -173,7 +173,7 @@ icc_new( IMAGE *in, IMAGE *out, VipsIntent intent ) icc->in_profile = 0; icc->out_profile = 0; icc->trans = 0; - icc->lock = g_mutex_new(); + icc->lock = vips_mutex_new(); if( im_add_close_callback( out, (im_callback_fn) icc_destroy, icc, NULL ) ) @@ -945,7 +945,7 @@ icc_destroy( Icc *icc ) IM_FREEF( cmsDeleteTransform, icc->trans ); IM_FREEF( cmsCloseProfile, icc->in_profile ); IM_FREEF( cmsCloseProfile, icc->out_profile ); - IM_FREEF( g_mutex_free, icc->lock ); + IM_FREEF( vips_mutex_free, icc->lock ); return( 0 ); } @@ -970,7 +970,7 @@ icc_new( IMAGE *in, IMAGE *out, VipsIntent intent ) icc->in_profile = 0; icc->out_profile = 0; icc->trans = 0; - icc->lock = g_mutex_new(); + icc->lock = vips_mutex_new(); if( im_add_close_callback( out, (im_callback_fn) icc_destroy, icc, NULL ) ) diff --git a/libvips/conversion/sequential.c b/libvips/conversion/sequential.c index 8a8efc65..e99afb65 100644 --- a/libvips/conversion/sequential.c +++ b/libvips/conversion/sequential.c @@ -100,7 +100,7 @@ vips_sequential_dispose( GObject *gobject ) { VipsSequential *sequential = (VipsSequential *) gobject; - VIPS_FREEF( g_mutex_free, sequential->lock ); + VIPS_FREEF( vips_mutex_free, sequential->lock ); VIPS_FREEF( g_cond_free, sequential->ready ); G_OBJECT_CLASS( vips_sequential_parent_class )->dispose( gobject ); @@ -293,7 +293,7 @@ static void vips_sequential_init( VipsSequential *sequential ) { sequential->trace = FALSE; - sequential->lock = g_mutex_new(); + sequential->lock = vips_mutex_new(); sequential->ready = g_cond_new(); sequential->tile_height = 1; sequential->error = 0; diff --git a/libvips/conversion/tilecache.c b/libvips/conversion/tilecache.c index 58d1c143..de2128c7 100644 --- a/libvips/conversion/tilecache.c +++ b/libvips/conversion/tilecache.c @@ -144,7 +144,7 @@ vips_block_cache_dispose( GObject *gobject ) VipsBlockCache *cache = (VipsBlockCache *) gobject; vips_block_cache_drop_all( cache ); - VIPS_FREEF( g_mutex_free, cache->lock ); + VIPS_FREEF( vips_mutex_free, cache->lock ); VIPS_FREEF( g_cond_free, cache->new_tile ); G_OBJECT_CLASS( vips_block_cache_parent_class )->dispose( gobject ); @@ -489,7 +489,7 @@ vips_block_cache_init( VipsBlockCache *cache ) cache->time = 0; cache->ntiles = 0; - cache->lock = g_mutex_new(); + cache->lock = vips_mutex_new(); cache->new_tile = g_cond_new(); cache->tiles = g_hash_table_new_full( (GHashFunc) vips_rect_hash, diff --git a/libvips/deprecated/im_tile_cache.c b/libvips/deprecated/im_tile_cache.c index 1fdc7b89..1c348835 100644 --- a/libvips/deprecated/im_tile_cache.c +++ b/libvips/deprecated/im_tile_cache.c @@ -105,7 +105,7 @@ tile_destroy( Tile *tile ) static void read_destroy( Read *read ) { - IM_FREEF( g_mutex_free, read->lock ); + IM_FREEF( vips_mutex_free, read->lock ); while( read->cache ) { Tile *tile = (Tile *) read->cache->data; @@ -131,7 +131,7 @@ read_new( IMAGE *in, IMAGE *out, read->max_tiles = max_tiles; read->time = 0; read->ntiles = 0; - read->lock = g_mutex_new(); + read->lock = vips_mutex_new(); read->cache = NULL; if( im_add_close_callback( out, diff --git a/libvips/foreign/fits.c b/libvips/foreign/fits.c index 07149673..74829da5 100644 --- a/libvips/foreign/fits.c +++ b/libvips/foreign/fits.c @@ -133,7 +133,7 @@ static void vips_fits_close( VipsFits *fits ) { VIPS_FREE( fits->filename ); - VIPS_FREEF( g_mutex_free, fits->lock ); + VIPS_FREEF( vips_mutex_free, fits->lock ); if( fits->fptr ) { int status; @@ -180,7 +180,7 @@ vips_fits_new_read( const char *filename, VipsImage *out, int band_select ) return( NULL ); } - fits->lock = g_mutex_new(); + fits->lock = vips_mutex_new(); return( fits ); } @@ -578,7 +578,7 @@ vips_fits_new_write( VipsImage *in, const char *filename ) return( NULL ); } - fits->lock = g_mutex_new(); + fits->lock = vips_mutex_new(); return( fits ); } diff --git a/libvips/foreign/magick2vips.c b/libvips/foreign/magick2vips.c index 44d615b3..860a1590 100644 --- a/libvips/foreign/magick2vips.c +++ b/libvips/foreign/magick2vips.c @@ -131,7 +131,7 @@ read_destroy( VipsImage *im, Read *read ) VIPS_FREEF( DestroyImageInfo, read->image_info ); VIPS_FREE( read->frames ); DestroyExceptionInfo( &read->exception ); - VIPS_FREEF( g_mutex_free, read->lock ); + VIPS_FREEF( vips_mutex_free, read->lock ); return( 0 ); } @@ -161,7 +161,7 @@ read_new( const char *filename, VipsImage *im ) read->n_frames = 0; read->frames = NULL; read->frame_height = 0; - read->lock = g_mutex_new(); + read->lock = vips_mutex_new(); g_signal_connect( im, "close", G_CALLBACK( read_destroy ), read ); diff --git a/libvips/foreign/vips2tiff.c b/libvips/foreign/vips2tiff.c index b673aacb..3caedd10 100644 --- a/libvips/foreign/vips2tiff.c +++ b/libvips/foreign/vips2tiff.c @@ -1075,7 +1075,7 @@ write_tif_tilewise( TiffWrite *tw ) return( -1 ); g_assert( !tw->write_lock ); - tw->write_lock = g_mutex_new(); + tw->write_lock = vips_mutex_new(); /* Write pyramid too? Only bother if bigger than tile size. */ @@ -1179,7 +1179,7 @@ free_tiff_write( TiffWrite *tw ) VIPS_FREEF( TIFFClose, tw->tif ); VIPS_FREEF( vips_free, tw->tbuf ); - VIPS_FREEF( g_mutex_free, tw->write_lock ); + VIPS_FREEF( vips_mutex_free, tw->write_lock ); VIPS_FREEF( free_pyramid, tw->layer ); VIPS_FREEF( vips_free, tw->icc_profile ); } diff --git a/libvips/include/vips/thread.h b/libvips/include/vips/thread.h index 77b32635..3a057370 100644 --- a/libvips/include/vips/thread.h +++ b/libvips/include/vips/thread.h @@ -43,40 +43,11 @@ extern "C" { */ #define VIPS__DEFAULT_STACK_SIZE (2 * 1024 * 1024) -#ifndef HAVE_THREADS -#undef g_thread_supported -#define g_thread_supported() (0) - -#define g_thread_init vips__g_thread_init -#define g_thread_join vips__g_thread_join -#define g_thread_self vips__g_thread_self -#define g_thread_create_full vips__g_thread_create_full - -/* We don't need a shadow imlementation of g_thread_create(), even though we - * use it, because it's just a macro over g_thread_create_full(). +/* We need wrappers over g_mutex_new(), it was replaced by g_mutex_init() in + * glib 2.32+ */ - -void vips__g_thread_init( GThreadFunctions *vtable ); -gpointer vips__g_thread_join( GThread * ); -gpointer vips__g_thread_self( void ); -GThread *vips__g_thread_create_full( GThreadFunc, - gpointer, gulong, gboolean, gboolean, GThreadPriority, GError ** ); - -#undef g_mutex_new -#undef g_mutex_free -#undef g_mutex_lock -#undef g_mutex_unlock - -#define g_mutex_new vips__g_mutex_new -#define g_mutex_free vips__g_mutex_free -#define g_mutex_lock vips__g_mutex_lock -#define g_mutex_unlock vips__g_mutex_unlock - -GMutex *vips__g_mutex_new( void ); -void vips__g_mutex_free( GMutex * ); -void vips__g_mutex_lock( GMutex * ); -void vips__g_mutex_unlock( GMutex * ); -#endif /*!HAVE_THREADS*/ +GMutex *vips_mutex_new( void ); +void vips_mutex_free( GMutex * ); #ifdef __cplusplus } diff --git a/libvips/iofuncs/buffer.c b/libvips/iofuncs/buffer.c index 1399bc51..189203a2 100644 --- a/libvips/iofuncs/buffer.c +++ b/libvips/iofuncs/buffer.c @@ -72,15 +72,8 @@ static GSList *vips__buffers_all = NULL; static int buffer_cache_n = 0; #endif /*DEBUG_CREATE*/ -#ifdef HAVE_THREADS static GPrivate *thread_buffer_cache_key = NULL; -#else /*!HAVE_THREADS*/ -static VipsBufferCache *thread_buffer_cache = NULL; -#endif /*HAVE_THREADS*/ -/* Only need this if we're threading and need to do a lot of start/stop. - */ -#ifdef HAVE_THREADS static void buffer_cache_free( VipsBufferCache *cache ) { @@ -95,7 +88,6 @@ buffer_cache_free( VipsBufferCache *cache ) VIPS_FREEF( g_hash_table_destroy, cache->hash ); VIPS_FREE( cache ); } -#endif /*HAVE_THREADS*/ static void buffer_cache_list_free( VipsBufferCacheList *cache_list ) @@ -163,16 +155,10 @@ buffer_cache_get( void ) { VipsBufferCache *cache; -#ifdef HAVE_THREADS if( !(cache = g_private_get( thread_buffer_cache_key )) ) { cache = buffer_cache_new(); g_private_set( thread_buffer_cache_key, cache ); } -#else /*!HAVE_THREADS*/ - if( !thread_buffer_cache ) - thread_buffer_cache = buffer_cache_new(); - cache = thread_buffer_cache; -#endif /*HAVE_THREADS*/ return( cache ); } @@ -474,9 +460,7 @@ vips_buffer_print( VipsBuffer *buffer ) void vips__buffer_init( void ) { -#ifdef HAVE_THREADS if( !thread_buffer_cache_key ) thread_buffer_cache_key = g_private_new( (GDestroyNotify) buffer_cache_free ); -#endif /*HAVE_THREADS*/ } diff --git a/libvips/iofuncs/cache.c b/libvips/iofuncs/cache.c index 02451609..d6838650 100644 --- a/libvips/iofuncs/cache.c +++ b/libvips/iofuncs/cache.c @@ -416,7 +416,7 @@ void vips__cache_init( void ) { if( !vips_cache_table ) { - vips_cache_lock = g_mutex_new(); + vips_cache_lock = vips_mutex_new(); vips_cache_table = g_hash_table_new( (GHashFunc) vips_operation_hash, diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index 4c7b4d07..8994508b 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -241,7 +241,7 @@ vips_image_finalize( GObject *gobject ) */ vips_image_delete( image ); - VIPS_FREEF( g_mutex_free, image->sslock ); + VIPS_FREEF( vips_mutex_free, image->sslock ); VIPS_FREE( image->Hist ); VIPS_FREEF( vips__gslist_gvalue_free, image->history_list ); @@ -1057,7 +1057,7 @@ vips_image_init( VipsImage *image ) image->Yres = 1.0; image->fd = -1; /* since 0 is stdout */ - image->sslock = g_mutex_new(); + image->sslock = vips_mutex_new(); image->sizeof_header = VIPS_SIZEOF_HEADER; diff --git a/libvips/iofuncs/init.c b/libvips/iofuncs/init.c index 9655a35d..8b129f2e 100644 --- a/libvips/iofuncs/init.c +++ b/libvips/iofuncs/init.c @@ -201,7 +201,7 @@ vips_init( const char *argv0 ) #endif /*G_THREADS_ENABLED*/ if( !vips__global_lock ) - vips__global_lock = g_mutex_new(); + vips__global_lock = vips_mutex_new(); VIPS_SETSTR( vips__argv0, argv0 ); diff --git a/libvips/iofuncs/memory.c b/libvips/iofuncs/memory.c index 79802b6b..d4fb8ef9 100644 --- a/libvips/iofuncs/memory.c +++ b/libvips/iofuncs/memory.c @@ -240,21 +240,13 @@ vips_tracked_free( void *s ) g_free( s ); } -/* g_mutex_new() is a macro. - */ -static void * -vips_tracked_mutex_new( void *data ) -{ - return( g_mutex_new() ); -} - static void vips_tracked_init( void ) { static GOnce vips_tracked_once = G_ONCE_INIT; vips_tracked_mutex = g_once( &vips_tracked_once, - vips_tracked_mutex_new, NULL ); + (GThreadFunc) vips_mutex_new, NULL ); } /** diff --git a/libvips/iofuncs/object.c b/libvips/iofuncs/object.c index 83a6e2de..9d89a41d 100644 --- a/libvips/iofuncs/object.c +++ b/libvips/iofuncs/object.c @@ -1271,7 +1271,7 @@ vips_object_class_init( VipsObjectClass *class ) if( !vips__object_all ) { vips__object_all = g_hash_table_new( g_direct_hash, g_direct_equal ); - vips__object_all_lock = g_mutex_new(); + vips__object_all_lock = vips_mutex_new(); } gobject_class->dispose = vips_object_dispose; diff --git a/libvips/iofuncs/semaphore.c b/libvips/iofuncs/semaphore.c index 3b4959b8..5ea8184c 100644 --- a/libvips/iofuncs/semaphore.c +++ b/libvips/iofuncs/semaphore.c @@ -58,19 +58,15 @@ vips_semaphore_init( VipsSemaphore *s, int v, char *name ) { s->v = v; s->name = name; -#ifdef HAVE_THREADS - s->mutex = g_mutex_new(); + s->mutex = vips_mutex_new(); s->cond = g_cond_new(); -#endif /*HAVE_THREADS*/ } void vips_semaphore_destroy( VipsSemaphore *s ) { -#ifdef HAVE_THREADS - VIPS_FREEF( g_mutex_free, s->mutex ); + VIPS_FREEF( vips_mutex_free, s->mutex ); VIPS_FREEF( g_cond_free, s->cond ); -#endif /*HAVE_THREADS*/ } /* Add n to the semaphore and signal any threads that are blocked waiting @@ -81,12 +77,10 @@ vips_semaphore_upn( VipsSemaphore *s, int n ) { int value_after_op; -#ifdef HAVE_THREADS g_mutex_lock( s->mutex ); -#endif /*HAVE_THREADS*/ s->v += n; value_after_op = s->v; -#ifdef HAVE_THREADS + /* If we are only incrementing by one, we only need to wake a single * thread. If we are incrementing by a lot, we must wake all threads. */ @@ -95,7 +89,6 @@ vips_semaphore_upn( VipsSemaphore *s, int n ) else g_cond_broadcast( s->cond ); g_mutex_unlock( s->mutex ); -#endif /*HAVE_THREADS*/ #ifdef DEBUG_IO printf( "vips_semaphore_upn(\"%s\",%d) = %d\n", @@ -122,16 +115,14 @@ vips_semaphore_downn( VipsSemaphore *s, int n ) { int value_after_op; -#ifdef HAVE_THREADS g_mutex_lock( s->mutex ); + while( s->v < n ) g_cond_wait( s->cond, s->mutex ); -#endif /*HAVE_THREADS*/ s->v -= n; value_after_op = s->v; -#ifdef HAVE_THREADS + g_mutex_unlock( s->mutex ); -#endif /*HAVE_THREADS*/ #ifdef DEBUG_IO printf( "vips_semaphore_downn(\"%s\",%d): %d\n", diff --git a/libvips/iofuncs/sinkdisc.c b/libvips/iofuncs/sinkdisc.c index d82d824a..621f2618 100644 --- a/libvips/iofuncs/sinkdisc.c +++ b/libvips/iofuncs/sinkdisc.c @@ -171,7 +171,6 @@ wbuffer_write( WriteBuffer *wbuffer ) &wbuffer->area, write->a ); } -#ifdef HAVE_THREADS /* Run this as a thread to do a BG write. */ static void * @@ -200,7 +199,6 @@ wbuffer_write_thread( void *data ) return( NULL ); } -#endif /*HAVE_THREADS*/ static WriteBuffer * wbuffer_new( Write *write ) @@ -227,7 +225,6 @@ wbuffer_new( Write *write ) */ vips__region_no_ownership( wbuffer->region ); -#ifdef HAVE_THREADS /* Make this last (picks up parts of wbuffer on startup). */ if( !(wbuffer->thread = g_thread_create( wbuffer_write_thread, wbuffer, @@ -237,7 +234,6 @@ wbuffer_new( Write *write ) wbuffer_free( wbuffer ); return( NULL ); } -#endif /*HAVE_THREADS*/ return( wbuffer ); } @@ -266,13 +262,7 @@ wbuffer_flush( Write *write ) /* Set the background writer going for this buffer. */ -#ifdef HAVE_THREADS vips_semaphore_up( &write->buf->go ); -#else - /* No threads? Write ourselves synchronously. - */ - wbuffer_write( write->buf ); -#endif /*HAVE_THREADS*/ return( 0 ); } diff --git a/libvips/iofuncs/sinkscreen.c b/libvips/iofuncs/sinkscreen.c index 9b3153e4..753164f7 100644 --- a/libvips/iofuncs/sinkscreen.c +++ b/libvips/iofuncs/sinkscreen.c @@ -66,14 +66,6 @@ #include #include -/* A have-threads we can test in if(). - */ -#ifdef HAVE_THREADS -static const int have_threads = 1; -#else /*!HAVE_THREADS*/ -static const int have_threads = 0; -#endif /*HAVE_THREADS*/ - #ifdef VIPS_DEBUG_AMBER static int render_num_renders = 0; #endif /*VIPS_DEBUG_AMBER*/ @@ -228,8 +220,8 @@ render_free( Render *render ) } g_mutex_unlock( render_dirty_lock ); - g_mutex_free( render->ref_count_lock ); - g_mutex_free( render->lock ); + vips_mutex_free( render->ref_count_lock ); + vips_mutex_free( render->lock ); vips_slist_map2( render->all, (VipsSListMap2Fn) tile_free, NULL, NULL ); VIPS_FREEF( g_slist_free, render->all ); @@ -520,15 +512,12 @@ render_thread_main( void *client ) static int render_thread_create( void ) { - if( !have_threads ) - return( 0 ); - if( !render_dirty_lock ) { - render_dirty_lock = g_mutex_new(); + render_dirty_lock = vips_mutex_new(); vips_semaphore_init( &render_dirty_sem, 0, "render_dirty_sem" ); } - if( !render_thread && have_threads ) { + if( !render_thread ) { if( !(render_thread = g_thread_create_full( render_thread_main, NULL, VIPS__DEFAULT_STACK_SIZE, TRUE, FALSE, @@ -595,7 +584,7 @@ render_new( VipsImage *in, VipsImage *out, VipsImage *mask, return( NULL ); render->ref_count = 1; - render->ref_count_lock = g_mutex_new(); + render->ref_count_lock = vips_mutex_new(); render->in = in; render->out = out; @@ -607,7 +596,7 @@ render_new( VipsImage *in, VipsImage *out, VipsImage *mask, render->notify = notify; render->a = a; - render->lock = g_mutex_new(); + render->lock = vips_mutex_new(); render->all = NULL; render->ntiles = 0; @@ -746,7 +735,7 @@ tile_queue( Tile *tile, VipsRegion *reg ) tile->painted = FALSE; tile_touch( tile ); - if( render->notify && have_threads ) { + if( render->notify ) { /* Add to the list of renders with dirty tiles. The bg * thread will pick it up and paint it. It can be already on * the dirty list. @@ -755,7 +744,7 @@ tile_queue( Tile *tile, VipsRegion *reg ) render_dirty_put( render ); } else { - /* No threads, or no notify ... paint the tile ourselves + /* no notify ... paint the tile ourselves * sychronously. No need to notify the client since they'll * never see black tiles. */ @@ -968,7 +957,6 @@ image_stop( void *seq, void *a, void *b ) static int mask_fill( VipsRegion *out, void *seq, void *a, void *b, gboolean *stop ) { -#ifdef HAVE_THREADS Render *render = (Render *) a; VipsRect *r = &out->valid; int x, y; @@ -1006,9 +994,6 @@ mask_fill( VipsRegion *out, void *seq, void *a, void *b, gboolean *stop ) } g_mutex_unlock( render->lock ); -#else /*!HAVE_THREADS*/ - vips_region_paint( out, &out->valid, 255 ); -#endif /*HAVE_THREADS*/ return( 0 ); } diff --git a/libvips/iofuncs/threadpool.c b/libvips/iofuncs/threadpool.c index 19435c63..7588de05 100644 --- a/libvips/iofuncs/threadpool.c +++ b/libvips/iofuncs/threadpool.c @@ -101,25 +101,34 @@ int vips__thinstrip_height = VIPS__THINSTRIP_HEIGHT; */ int vips__concurrency = 0; -#ifndef HAVE_THREADS -/* If we're building without gthread, we need stubs for the g_thread_*() and - * g_mutex_*() functions. has #defines which point the g_ - * names here. +/* Glib 2.32 revised the thread API. We need some compat functions. */ -void vips__g_thread_init( GThreadFunctions *vtable ) {} -gpointer vips__g_thread_join( GThread *dummy ) { return( NULL ); } -gpointer vips__g_thread_self( void ) { return( NULL ); } -GThread *vips__g_thread_create_full( GThreadFunc d1, - gpointer d2, gulong d3, gboolean d4, gboolean d5, GThreadPriority d6, - GError **d7 ) - { return( NULL ); } +GMutex * +vips_mutex_new( void ) +{ + GMutex *mutex; -GMutex *vips__g_mutex_new( void ) { return( NULL ); } -void vips__g_mutex_free( GMutex *d ) {} -void vips__g_mutex_lock( GMutex *d ) {} -void vips__g_mutex_unlock( GMutex *d ) {} -#endif /*!HAVE_THREADS*/ +#ifdef HAVE_MUTEX_INIT + mutex = g_new( GMutex, 1 ); + g_mutex_init( mutex ); +#else + mutex = g_mutex_new(); +#endif + + return( mutex ); +} + +void +vips_mutex_free( GMutex *mutex ) +{ +#ifdef HAVE_MUTEX_INIT + g_mutex_clear( mutex ); + g_free( mutex ); +#else + g_mutex_free( mutex ); +#endif +} /** * vips_concurrency_set: @@ -564,7 +573,6 @@ vips_thread_work_unit( VipsThread *thr ) } } -#ifdef HAVE_THREADS /* What runs as a thread ... loop, waiting to be told to do stuff. */ static void * @@ -592,7 +600,6 @@ vips_thread_main_loop( void *a ) return( NULL ); } -#endif /*HAVE_THREADS*/ /* Attach another thread to a threadpool. */ @@ -628,7 +635,6 @@ vips_thread_new( VipsThreadpool *pool ) } #endif /*TIME_THREAD*/ -#ifdef HAVE_THREADS /* Make a worker thread. We have to use g_thread_create_full() because * we need to insist on a non-tiny stack. Some platforms default to * very small values (eg. various BSDs). @@ -643,7 +649,6 @@ vips_thread_new( VipsThreadpool *pool ) } VIPS_DEBUG_MSG_RED( "vips_thread_new: g_thread_create_full()\n" ); -#endif /*HAVE_THREADS*/ return( thr ); } @@ -674,7 +679,7 @@ vips_threadpool_free( VipsThreadpool *pool ) pool->im->filename, pool ); vips_threadpool_kill_threads( pool ); - VIPS_FREEF( g_mutex_free, pool->allocate_lock ); + VIPS_FREEF( vips_mutex_free, pool->allocate_lock ); vips_semaphore_destroy( &pool->finish ); vips_semaphore_destroy( &pool->tick ); @@ -699,7 +704,7 @@ vips_threadpool_new( VipsImage *im ) pool->im = im; pool->allocate = NULL; pool->work = NULL; - pool->allocate_lock = g_mutex_new(); + pool->allocate_lock = vips_mutex_new(); pool->nthr = vips_concurrency_get(); pool->thr = NULL; vips_semaphore_init( &pool->finish, 0, "finish" ); @@ -879,15 +884,9 @@ vips_threadpool_run( VipsImage *im, } for(;;) { -#ifdef HAVE_THREADS /* Wait for a tick from a worker. */ vips_semaphore_down( &pool->tick ); -#else - /* No threads, do the work ourselves in the main thread. - */ - vips_thread_work_unit( pool->thr[0] ); -#endif /*HAVE_THREADS*/ VIPS_DEBUG_MSG( "vips_threadpool_run: tick\n" ); diff --git a/libvips/mosaicing/im_lrmerge.c b/libvips/mosaicing/im_lrmerge.c index 61f8495c..7149111e 100644 --- a/libvips/mosaicing/im_lrmerge.c +++ b/libvips/mosaicing/im_lrmerge.c @@ -680,7 +680,7 @@ lr_blend_labpack( REGION *or, MergeInfo *inf, Overlapping *ovlap, Rect *oreg ) static void * lock_free( GMutex *lock ) { - g_mutex_free( lock ); + vips_mutex_free( lock ); return( NULL ); } @@ -767,10 +767,10 @@ im__build_mergestate( const char *domain, for( x = 0; x < ovlap->flsize; x++ ) ovlap->first[x] = -1; - ovlap->fl_lock = g_mutex_new(); + ovlap->fl_lock = vips_mutex_new(); if( im_add_close_callback( out, (im_callback_fn) lock_free, ovlap->fl_lock, NULL ) ) { - g_mutex_free( ovlap->fl_lock ); + vips_mutex_free( ovlap->fl_lock ); return( NULL ); }