Merge commit '4c263a36e9e728b5ab5cc1f4f3cafe5738a6b6e7' into 8.11
This commit is contained in:
commit
939437d56e
@ -5703,16 +5703,3 @@ vips_popenf( const char *fmt, const char *mode, ... )
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
GThread *
|
||||
vips_g_thread_new( const char *domain, GThreadFunc func, gpointer data )
|
||||
{
|
||||
vips_error( "vips_g_thread_new", "%s", _( "deprecated" ) );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
void *
|
||||
vips_g_thread_join( GThread *thread )
|
||||
{
|
||||
vips_error( "vips_g_thread_join", "%s", _( "deprecated" ) );
|
||||
return( NULL );
|
||||
}
|
||||
|
@ -47,6 +47,11 @@ void vips_g_mutex_free( GMutex * );
|
||||
GCond *vips_g_cond_new( void );
|
||||
void vips_g_cond_free( GCond * );
|
||||
|
||||
/* ... and for GThread.
|
||||
*/
|
||||
GThread *vips_g_thread_new( const char *, GThreadFunc, gpointer );
|
||||
void *vips_g_thread_join( GThread *thread );
|
||||
|
||||
gboolean vips_thread_isworker( void );
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -1224,11 +1224,6 @@ VipsWindow *vips_window_ref( VipsImage *im, int top, int height );
|
||||
FILE *vips_popenf( const char *fmt, const char *mode, ... )
|
||||
__attribute__((format(printf, 1, 3)));
|
||||
|
||||
/* old GThread API.
|
||||
*/
|
||||
GThread *vips_g_thread_new( const char *, GThreadFunc, gpointer );
|
||||
void *vips_g_thread_join( GThread *thread );
|
||||
|
||||
/* This stuff is very, very old and should not be used by anyone now.
|
||||
*/
|
||||
#ifdef VIPS_ENABLE_ANCIENT
|
||||
|
@ -167,29 +167,22 @@ typedef struct _RenderThreadStateClass {
|
||||
|
||||
G_DEFINE_TYPE( RenderThreadState, render_thread_state, VIPS_TYPE_THREAD_STATE );
|
||||
|
||||
/* A boolean indicating if the bg render thread is running.
|
||||
/* The BG thread which sits waiting to do some calculations, and the semaphore
|
||||
* it waits on holding the number of renders with dirty tiles.
|
||||
*/
|
||||
static gboolean render_running = FALSE;
|
||||
static GThread *render_thread = NULL;
|
||||
|
||||
/* Set this to ask the render thread to quit.
|
||||
*/
|
||||
static gboolean render_kill = FALSE;
|
||||
|
||||
/* All the renders with dirty tiles.
|
||||
/* All the renders with dirty tiles, and a semaphore that the bg render thread
|
||||
* waits on.
|
||||
*/
|
||||
static GMutex *render_dirty_lock = NULL;
|
||||
static GSList *render_dirty_all = NULL;
|
||||
|
||||
/* A semaphore where the bg render thread waits on holding the number of
|
||||
* renders with dirty tiles
|
||||
*/
|
||||
static VipsSemaphore n_render_dirty_sem;
|
||||
|
||||
/* A semaphore where the main thread waits for when the bg render thread
|
||||
* is shutdown.
|
||||
*/
|
||||
static VipsSemaphore render_finish;
|
||||
|
||||
/* Set this to make the bg thread stop and reschedule.
|
||||
*/
|
||||
static gboolean render_reschedule = FALSE;
|
||||
@ -452,7 +445,10 @@ vips__render_shutdown( void )
|
||||
if( render_dirty_lock ) {
|
||||
g_mutex_lock( render_dirty_lock );
|
||||
|
||||
if( render_running ) {
|
||||
if( render_thread ) {
|
||||
GThread *thread;
|
||||
|
||||
thread = render_thread;
|
||||
render_reschedule = TRUE;
|
||||
render_kill = TRUE;
|
||||
|
||||
@ -460,16 +456,13 @@ vips__render_shutdown( void )
|
||||
|
||||
vips_semaphore_up( &n_render_dirty_sem );
|
||||
|
||||
vips_semaphore_down( &render_finish );
|
||||
|
||||
render_running = FALSE;
|
||||
(void) vips_g_thread_join( thread );
|
||||
}
|
||||
else
|
||||
g_mutex_unlock( render_dirty_lock );
|
||||
|
||||
VIPS_FREEF( vips_g_mutex_free, render_dirty_lock );
|
||||
vips_semaphore_destroy( &n_render_dirty_sem );
|
||||
vips_semaphore_destroy( &render_finish );
|
||||
}
|
||||
}
|
||||
|
||||
@ -1008,8 +1001,8 @@ render_dirty_get( void )
|
||||
|
||||
/* Loop for the background render manager thread.
|
||||
*/
|
||||
static void
|
||||
render_thread_main( void *data, void *user_data )
|
||||
static void *
|
||||
render_thread_main( void *client )
|
||||
{
|
||||
Render *render;
|
||||
|
||||
@ -1044,29 +1037,23 @@ render_thread_main( void *data, void *user_data )
|
||||
}
|
||||
}
|
||||
|
||||
/* We are exiting: tell the main thread.
|
||||
/* We are exiting, so render_thread must now be NULL.
|
||||
*/
|
||||
vips_semaphore_up( &render_finish );
|
||||
render_thread = NULL;
|
||||
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
static void *
|
||||
vips__sink_screen_init( void *data )
|
||||
{
|
||||
g_assert( !render_running );
|
||||
g_assert( !render_thread );
|
||||
g_assert( !render_dirty_lock );
|
||||
|
||||
render_dirty_lock = vips_g_mutex_new();
|
||||
vips_semaphore_init( &n_render_dirty_sem, 0, "n_render_dirty" );
|
||||
vips_semaphore_init( &render_finish, 0, "render_finish" );
|
||||
|
||||
if( vips__thread_execute( "sink_screen", render_thread_main,
|
||||
NULL ) ) {
|
||||
vips_error( "vips_sink_screen_init",
|
||||
"%s", _( "unable to init render thread" ) );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
render_running = TRUE;
|
||||
render_thread = vips_g_thread_new( "sink_screen",
|
||||
render_thread_main, NULL );
|
||||
|
||||
return( NULL );
|
||||
}
|
||||
|
@ -182,6 +182,77 @@ vips_thread_isworker( void )
|
||||
return( g_private_get( is_worker_key ) != NULL );
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
const char *domain;
|
||||
GThreadFunc func;
|
||||
gpointer data;
|
||||
} VipsThreadInfo;
|
||||
|
||||
static void *
|
||||
vips_thread_run( gpointer data )
|
||||
{
|
||||
VipsThreadInfo *info = (VipsThreadInfo *) data;
|
||||
|
||||
void *result;
|
||||
|
||||
/* Set this to something (anything) to tag this thread as a vips
|
||||
* worker.
|
||||
*/
|
||||
g_private_set( is_worker_key, data );
|
||||
|
||||
if( vips__thread_profile )
|
||||
vips__thread_profile_attach( info->domain );
|
||||
|
||||
result = info->func( info->data );
|
||||
|
||||
g_free( info );
|
||||
|
||||
vips_thread_shutdown();
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
||||
GThread *
|
||||
vips_g_thread_new( const char *domain, GThreadFunc func, gpointer data )
|
||||
{
|
||||
GThread *thread;
|
||||
VipsThreadInfo *info;
|
||||
GError *error = NULL;
|
||||
|
||||
info = g_new( VipsThreadInfo, 1 );
|
||||
info->domain = domain;
|
||||
info->func = func;
|
||||
info->data = data;
|
||||
|
||||
thread = g_thread_try_new( domain, vips_thread_run, info, &error );
|
||||
|
||||
VIPS_DEBUG_MSG_RED( "vips_g_thread_new: g_thread_create( %s ) = %p\n",
|
||||
domain, thread );
|
||||
|
||||
if( !thread ) {
|
||||
if( error )
|
||||
vips_g_error( &error );
|
||||
else
|
||||
vips_error( domain,
|
||||
"%s", _( "unable to create thread" ) );
|
||||
}
|
||||
|
||||
return( thread );
|
||||
}
|
||||
|
||||
void *
|
||||
vips_g_thread_join( GThread *thread )
|
||||
{
|
||||
void *result;
|
||||
|
||||
result = g_thread_join( thread );
|
||||
|
||||
VIPS_DEBUG_MSG_RED( "vips_g_thread_join: g_thread_join( %p )\n",
|
||||
thread );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
/* An name for this thread.
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user