diff --git a/mail/em-utils.c b/mail/em-utils.c
index 7685e76..3a3f23b 100644
--- a/mail/em-utils.c
+++ b/mail/em-utils.c
@@ -1986,8 +1986,55 @@ struct TryOpenEBookStruct {
 	GError **error;
 	EFlag *flag;
 	gboolean result;
+
+	gint ref_count;
 };
 
+static struct TryOpenEBookStruct *
+create_try_open (GError **error, EFlag *flag)
+{
+	struct TryOpenEBookStruct *res;
+
+	res = g_new0 (struct TryOpenEBookStruct, 1);
+
+	res->error = error;
+	res->flag = flag;
+	res->result = FALSE;
+
+	g_atomic_int_set (&res->ref_count, 1);
+
+	return res;
+}
+
+static void
+unref_try_open (struct TryOpenEBookStruct *s)
+{
+	g_return_if_fail (s != NULL);
+
+	if (g_atomic_int_dec_and_test (&s->ref_count)) {
+		e_flag_free (s->flag);
+		s->flag = NULL;
+		g_free (s);
+	}
+}
+
+static gboolean
+ref_try_open (struct TryOpenEBookStruct *s)
+{
+	gint ref_count;
+
+	g_return_val_if_fail (s != NULL, FALSE);
+
+	ref_count = g_atomic_int_exchange_and_add (&s->ref_count, 1);
+
+	if (ref_count > 0)
+		return TRUE;
+
+	g_atomic_int_set (&s->ref_count, ref_count);
+
+	return FALSE;
+}
+
 static void
 try_open_e_book_cb (EBook *book, EBookStatus status, gpointer closure)
 {
@@ -1996,6 +2046,9 @@ try_open_e_book_cb (EBook *book, EBookStatus status, gpointer closure)
 	if (!data)
 		return;
 
+	if (!ref_try_open (data))
+		return;
+
 	data->result = status == E_BOOK_ERROR_OK;
 
 	if (!data->result) {
@@ -2004,6 +2056,7 @@ try_open_e_book_cb (EBook *book, EBookStatus status, gpointer closure)
 	}
 
 	e_flag_set (data->flag);
+	unref_try_open (data);
 }
 
 /**
@@ -2016,28 +2069,26 @@ try_open_e_book_cb (EBook *book, EBookStatus status, gpointer closure)
 static gboolean
 try_open_e_book (EBook *book, gboolean only_if_exists, GError **error)
 {
-	struct TryOpenEBookStruct data;
-	gboolean canceled = FALSE;
-	EFlag *flag = e_flag_new ();
+	struct TryOpenEBookStruct *data;
+	gboolean canceled = FALSE, result;
 
-	data.error = error;
-	data.flag = flag;
-	data.result = FALSE;
+	data = create_try_open (error, e_flag_new ());
 
-	if (e_book_async_open (book, only_if_exists, try_open_e_book_cb, &data) != FALSE) {
-		e_flag_free (flag);
+	if (e_book_async_open (book, only_if_exists, try_open_e_book_cb, data) != FALSE) {
+		data->error = NULL;
+		unref_try_open (data);
 		g_clear_error (error);
 		g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_OTHER_ERROR, "Failed to call e_book_async_open.");
 		return FALSE;
 	}
 
-	while (canceled = camel_operation_cancel_check (NULL), !canceled && !e_flag_is_set (flag)) {
+	while (canceled = camel_operation_cancel_check (NULL), !canceled && !e_flag_is_set (data->flag)) {
 		GTimeVal wait;
 
 		g_get_current_time (&wait);
 		g_time_val_add (&wait, 250000); /* waits 250ms */
 
-		e_flag_timed_wait (flag, &wait);
+		e_flag_timed_wait (data->flag, &wait);
 	}
 
 	if (canceled) {
@@ -2045,13 +2096,15 @@ try_open_e_book (EBook *book, gboolean only_if_exists, GError **error)
 		g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CANCELLED, "Operation has been canceled.");
 		e_book_cancel_async_op (book, NULL);
 		/* it had been canceled, the above callback may not be called, thus setting flag here */
-		e_flag_set (flag);
+		e_flag_set (data->flag);
 	}
 
-	e_flag_wait (flag);
-	e_flag_free (flag);
+	e_flag_wait (data->flag);
+	data->error = NULL;
+	result = data->result;
+	unref_try_open (data);
 
-	return data.result && (!error || !*error);
+	return result && (!error || !*error);
 }
 
 static gboolean
