mirror of https://github.com/GNOME/gimp.git
app: in bucket-fill tool, cancel async on tool destruction
When computing line-art, don't ref the bucket-fill tool in the async data, and rather cancel any ongoing async upon tool destruction, so that the async callback doesn't attept to touch the now-dead tool. This avoids segfaulting in the async callback when switching to a different tool, while a line-art async operation is active. Additionally, always cancel any previous async operation in gimp_bucket_fill_compute_line_art(), even if not starting a new one.
This commit is contained in:
parent
62baffed98
commit
663a6c7011
|
@ -232,6 +232,17 @@ gimp_bucket_fill_tool_finalize (GObject *object)
|
|||
GimpImage *image = g_weak_ref_get (&tool->priv->cached_image);
|
||||
GimpDrawable *drawable = g_weak_ref_get (&tool->priv->cached_drawable);
|
||||
|
||||
if (tool->priv->async)
|
||||
{
|
||||
/* we cancel the async, but don't wait for it to finish, since
|
||||
* it can't actually be interrupted. instead
|
||||
* gimp_bucket_fill_compute_line_art_cb() bails if the async has
|
||||
* been canceled, to avoid accessing the dead tool.
|
||||
*/
|
||||
gimp_cancelable_cancel (GIMP_CANCELABLE (tool->priv->async));
|
||||
g_clear_object (&tool->priv->async);
|
||||
}
|
||||
|
||||
g_clear_object (&tool->priv->line_art);
|
||||
|
||||
if (image)
|
||||
|
@ -680,17 +691,15 @@ gimp_bucket_fill_tool_cursor_update (GimpTool *tool,
|
|||
|
||||
typedef struct
|
||||
{
|
||||
GimpBucketFillTool *tool;
|
||||
GimpPickable *pickable;
|
||||
gboolean fill_transparent;
|
||||
gdouble line_art_threshold;
|
||||
GimpPickable *pickable;
|
||||
gboolean fill_transparent;
|
||||
gdouble line_art_threshold;
|
||||
} PrecomputeData;
|
||||
|
||||
static void
|
||||
precompute_data_free (PrecomputeData *data)
|
||||
{
|
||||
g_object_unref (data->pickable);
|
||||
g_object_unref (data->tool);
|
||||
g_slice_free (PrecomputeData, data);
|
||||
}
|
||||
|
||||
|
@ -731,6 +740,12 @@ gimp_bucket_fill_compute_line_art (GimpBucketFillTool *tool)
|
|||
return;
|
||||
}
|
||||
|
||||
if (tool->priv->async)
|
||||
{
|
||||
gimp_cancelable_cancel (GIMP_CANCELABLE (tool->priv->async));
|
||||
g_clear_object (&tool->priv->async);
|
||||
}
|
||||
|
||||
g_clear_object (&tool->priv->line_art);
|
||||
if (options->fill_criterion == GIMP_SELECT_CRITERION_LINE_ART)
|
||||
{
|
||||
|
@ -758,16 +773,10 @@ gimp_bucket_fill_compute_line_art (GimpBucketFillTool *tool)
|
|||
{
|
||||
PrecomputeData *data = g_slice_new (PrecomputeData);
|
||||
|
||||
data->tool = g_object_ref (tool);
|
||||
data->pickable = pickable;
|
||||
data->fill_transparent = options->fill_transparent;
|
||||
data->line_art_threshold = options->line_art_threshold;
|
||||
|
||||
if (tool->priv->async)
|
||||
{
|
||||
gimp_cancelable_cancel (GIMP_CANCELABLE (tool->priv->async));
|
||||
g_object_unref (tool->priv->async);
|
||||
}
|
||||
tool->priv->async = gimp_parallel_run_async_full (1,
|
||||
(GimpParallelRunAsyncFunc) gimp_bucket_fill_compute_line_art_async,
|
||||
data, (GDestroyNotify) precompute_data_free);
|
||||
|
|
Loading…
Reference in New Issue