Fix bug #2398, "Race when closing compose during drafting"
authorColin Leroy <colin@colino.net>
Wed, 30 Apr 2014 20:48:13 +0000 (22:48 +0200)
committerColin Leroy <colin@colino.net>
Wed, 30 Apr 2014 20:48:13 +0000 (22:48 +0200)
Thanks to Michael Schwendt for spotting the problem.

src/compose.c
src/compose.h

index 41f0554..6f4c8b9 100644 (file)
@@ -11453,16 +11453,28 @@ gboolean compose_close(Compose *compose)
 {
        gint x, y;
 
+       cm_return_val_if_fail(compose, FALSE);
+
        if (!g_mutex_trylock(compose->mutex)) {
                /* we have to wait for the (possibly deferred by auto-save)
                 * drafting to be done, before destroying the compose under
                 * it. */
                debug_print("waiting for drafting to finish...\n");
                compose_allow_user_actions(compose, FALSE);
-               g_timeout_add (500, (GSourceFunc) compose_close, compose);
+               if (compose->close_timeout_tag == 0) {
+                       compose->close_timeout_tag = 
+                               g_timeout_add (500, (GSourceFunc) compose_close,
+                               compose);
+               }
                return FALSE;
        }
-       cm_return_val_if_fail(compose, FALSE);
+       
+       if (compose->close_timeout_tag) {
+               /* let the close be done by the deferred callback */
+               g_mutex_unlock(compose->mutex);
+               return FALSE;
+       }
+
        gtkut_widget_get_uposition(compose->window, &x, &y);
        if (!compose->batch) {
                prefs_common.compose_x = x;
index 992989b..2d08a3b 100644 (file)
@@ -235,6 +235,7 @@ struct _Compose
 
        gboolean automatic_break;
        GMutex *mutex;
+       gint close_timeout_tag;
        gchar *orig_charset;
        gint set_cursor_pos;