[gimp] app: in bucket-fill tool, cancel async on tool destruction
- From: Ell <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: in bucket-fill tool, cancel async on tool destruction
- Date: Mon, 19 Nov 2018 20:07:43 +0000 (UTC)
commit 663a6c701131c17e1222083560ed1b1102087e6b
Author: Ell <ell_se yahoo com>
Date: Mon Nov 19 14:25:51 2018 -0500
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.
app/tools/gimpbucketfilltool.c | 31 ++++++++++++++++++++-----------
1 file changed, 20 insertions(+), 11 deletions(-)
---
diff --git a/app/tools/gimpbucketfilltool.c b/app/tools/gimpbucketfilltool.c
index dc3e18b020..9ce209c714 100644
--- a/app/tools/gimpbucketfilltool.c
+++ b/app/tools/gimpbucketfilltool.c
@@ -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);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]