app: add "independent" parameter to gimp_parallel_run_async()

Add a boolean "independent" parameter to gimp_parallel_run_async().
When FALSE, the passed function is run in the shared async thread
pool; when TRUE, the passed function is run in an independent
thread.

Generally, async operations should run in the async pool, however,
it might be desirable to run long-standing operations, especially
ones that can't be canceled, in independent threads.  This avoids
stalling quicker operations, and shutdown.

Adapt the rest of the code for the change.  In particular,
initialize the font cache in an independent thread.
This commit is contained in:
Ell 2018-05-27 13:02:25 -04:00
parent 3958ffbe50
commit ad8add6808
4 changed files with 58 additions and 29 deletions

View File

@ -153,7 +153,8 @@ gimp_parallel_exit (Gimp *gimp)
}
GimpAsync *
gimp_parallel_run_async (GimpParallelRunAsyncFunc func,
gimp_parallel_run_async (gboolean independent,
GimpParallelRunAsyncFunc func,
gpointer user_data)
{
GimpAsync *async;
@ -169,30 +170,48 @@ gimp_parallel_run_async (GimpParallelRunAsyncFunc func,
task->func = func;
task->user_data = user_data;
if (gimp_parallel_run_async_n_threads > 0)
if (independent)
{
GList *link;
GThread *thread = g_thread_new (
"async-ind",
(GThreadFunc) gimp_parallel_run_async_execute_task,
task);
link = g_list_alloc ();
link->data = task;
g_object_set_data (G_OBJECT (async),
"gimp-parallel-run-async-link", link);
g_signal_connect_after (async, "cancel",
G_CALLBACK (gimp_parallel_run_async_cancel),
NULL);
g_mutex_lock (&gimp_parallel_run_async_mutex);
g_queue_push_tail_link (&gimp_parallel_run_async_queue, link);
g_cond_signal (&gimp_parallel_run_async_cond);
g_mutex_unlock (&gimp_parallel_run_async_mutex);
gimp_async_add_callback (async,
[] (GimpAsync *async,
gpointer thread)
{
g_thread_join ((GThread *) thread);
},
thread);
}
else
{
gimp_parallel_run_async_execute_task (task);
if (gimp_parallel_run_async_n_threads > 0)
{
GList *link;
link = g_list_alloc ();
link->data = task;
g_object_set_data (G_OBJECT (async),
"gimp-parallel-run-async-link", link);
g_signal_connect_after (async, "cancel",
G_CALLBACK (gimp_parallel_run_async_cancel),
NULL);
g_mutex_lock (&gimp_parallel_run_async_mutex);
g_queue_push_tail_link (&gimp_parallel_run_async_queue, link);
g_cond_signal (&gimp_parallel_run_async_cond);
g_mutex_unlock (&gimp_parallel_run_async_mutex);
}
else
{
gimp_parallel_run_async_execute_task (task);
}
}
return async;

View File

@ -38,7 +38,8 @@ typedef void (* GimpParallelDistributeAreaFunc) (const GeglRectangle *area,
void gimp_parallel_init (Gimp *gimp);
void gimp_parallel_exit (Gimp *gimp);
GimpAsync * gimp_parallel_run_async (GimpParallelRunAsyncFunc func,
GimpAsync * gimp_parallel_run_async (gboolean independent,
GimpParallelRunAsyncFunc func,
gpointer user_data);
void gimp_parallel_distribute (gint max_n,
@ -62,13 +63,15 @@ extern "C++"
template <class ParallelRunAsyncFunc>
inline GimpAsync *
gimp_parallel_run_async (ParallelRunAsyncFunc func)
gimp_parallel_run_async (gboolean independent,
ParallelRunAsyncFunc func)
{
ParallelRunAsyncFunc *func_copy = g_new (ParallelRunAsyncFunc, 1);
new (func_copy) ParallelRunAsyncFunc (func);
return gimp_parallel_run_async ([] (GimpAsync *async,
return gimp_parallel_run_async (independent,
[] (GimpAsync *async,
gpointer user_data)
{
ParallelRunAsyncFunc *func_copy =
@ -78,7 +81,8 @@ gimp_parallel_run_async (ParallelRunAsyncFunc func)
func_copy->~ParallelRunAsyncFunc ();
g_free (func_copy);
}, func_copy);
},
func_copy);
}
template <class ParallelDistributeFunc>
@ -95,7 +99,8 @@ gimp_parallel_distribute (gint max_n,
*(const ParallelDistributeFunc *) user_data);
func_copy (i, n);
}, &func);
},
&func);
}
template <class ParallelDistributeRangeFunc>
@ -113,7 +118,8 @@ gimp_parallel_distribute_range (gsize size,
*(const ParallelDistributeRangeFunc *) user_data);
func_copy (offset, size);
}, &func);
},
&func);
}
template <class ParallelDistributeAreaFunc>
@ -130,7 +136,8 @@ gimp_parallel_distribute_area (const GeglRectangle *area,
*(const ParallelDistributeAreaFunc *) user_data);
func_copy (area);
}, &func);
},
&func);
}
}

View File

@ -348,6 +348,7 @@ gimp_histogram_calculate_async (GimpHistogram *histogram,
}
histogram->priv->calculate_async = gimp_parallel_run_async (
FALSE,
(GimpParallelRunAsyncFunc) gimp_histogram_calculate_internal,
context);

View File

@ -163,8 +163,10 @@ gimp_fonts_load (Gimp *gimp,
* in the case a cache rebuild is to be done it will not block
* the UI.
*/
async = gimp_parallel_run_async ((GimpParallelRunAsyncFunc) gimp_fonts_load_async,
config);
async = gimp_parallel_run_async (
TRUE,
(GimpParallelRunAsyncFunc) gimp_fonts_load_async,
config);
gimp_async_add_callback (async,
(GimpAsyncCallback) gimp_fonts_load_async_callback,
gimp);