From 6946c3b9d9a047fbef5014341ced1ef4ad4d4be3 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 14 Jul 2021 20:21:38 +0100 Subject: [PATCH] start up threadpool later might help php and ruby web frameworks see eg. https://github.com/libvips/php-vips-ext/issues/42 --- ChangeLog | 7 +++++-- configure.ac | 6 +++--- libvips/iofuncs/threadpool.c | 27 ++++++++++++++++++++++----- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index aa74552c..9193ae51 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,12 @@ -14/8/20 started 8.11.2 +14/7/21 started 8.11.3 +- build threadpool later [kleisauke] + +15/6/20 started 8.11.2 - better libdir guessing [remi] - fix tiff pyramid creation with jp2k compression (was broken by 8.11.1) - don't load modules if we're built without modules -14/8/20 started 8.11.1 +18/6/21 started 8.11.1 - add more example code to C docs - update libtool support in configure.ac - more startup info if VIPS_INFO is set diff --git a/configure.ac b/configure.ac index 6e7815c7..b6009ba2 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # also update the version number in the m4 macros below -AC_INIT([vips],[8.11.2],[vipsip@jiscmail.ac.uk]) +AC_INIT([vips],[8.11.3],[vipsip@jiscmail.ac.uk]) # required for gobject-introspection AC_PREREQ([2.69]) @@ -18,7 +18,7 @@ AC_CONFIG_MACRO_DIR([m4]) # user-visible library versioning m4_define([vips_major_version], [8]) m4_define([vips_minor_version], [11]) -m4_define([vips_micro_version], [2]) +m4_define([vips_micro_version], [3]) m4_define([vips_version], [vips_major_version.vips_minor_version.vips_micro_version]) @@ -43,7 +43,7 @@ VIPS_LIBS="" # binary interface changes not backwards compatible?: reset age to 0 LIBRARY_CURRENT=55 -LIBRARY_REVISION=1 +LIBRARY_REVISION=2 LIBRARY_AGE=13 # patched into include/vips/version.h diff --git a/libvips/iofuncs/threadpool.c b/libvips/iofuncs/threadpool.c index 9fa53881..7f04141e 100644 --- a/libvips/iofuncs/threadpool.c +++ b/libvips/iofuncs/threadpool.c @@ -731,6 +731,19 @@ vips_task_free( VipsTask *task ) VIPS_FREE( task ); } +static void * +vips__thread_once_init( void *data ) +{ + /* We can have many more than vips__concurrency threads -- each active + * pipeline will make vips__concurrency more, see + * vips_threadpool_run(). + */ + vips__pool = g_thread_pool_new( vips_thread_main_loop, NULL, + -1, FALSE, NULL ); + + return( NULL ); +} + /** * vips__thread_execute: * @name: a name for the thread @@ -747,10 +760,14 @@ vips_task_free( VipsTask *task ) int vips__thread_execute( const char *name, GFunc func, gpointer data ) { + static GOnce once = G_ONCE_INIT; + VipsThreadExec *exec; GError *error = NULL; gboolean result; + VIPS_ONCE( &once, vips__thread_once_init, NULL ); + exec = g_new( VipsThreadExec, 1 ); exec->name = name; exec->func = func; @@ -948,12 +965,12 @@ vips__threadpool_init( void ) if( vips__concurrency == 0 ) vips__concurrency = vips__concurrency_get_default(); - /* We can have many more than vips__concurrency threads -- each active - * pipeline will make vips__concurrency more, see - * vips_threadpool_run(). + /* The threadpool is built in the first vips__thread_execute() + * call, since we want thread creation to happen as late as possible. + * + * Many web platforms start up in a base environment, then fork() for + * each request. We must not make the threadpool before the fork. */ - vips__pool = g_thread_pool_new( vips_thread_main_loop, NULL, - -1, FALSE, NULL ); VIPS_DEBUG_MSG( "vips__threadpool_init: (%p)\n", vips__pool ); }