From: Matthew Barnes Date: Wed, 24 Oct 2012 21:28:25 +0000 (-0400) Subject: IMAPX: Explicitly pass GCancellable and GError to callbacks. X-Git-Tag: upstream/3.7.4~290 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ff1949841d60850409093a666f819e5c963e81ba;p=platform%2Fupstream%2Fevolution-data-server.git IMAPX: Explicitly pass GCancellable and GError to callbacks. Further error handling improvements. This involves some public API changes, but the impact is limited to evolution-kolab. * CamelIMAPXCommandFunc now takes a GCancellable argument in addition to its GError argument. * The public GCancellable member of CamelIMAPXJob is now private, and the public GError member is removed. * The start() method of CamelIMAPXJob now takes a GCancellable and GError argument. The GCancellable pass through this method call is always the CamelIMAPXJob's own private GCancellable. * A new camel_imapx_job_cancel() function which simply cancels the CamelIMAPXJob's internal GCancellable. Additional changes internal to CamelIMAPXServer are: * Adapt operations to the new callback function signatures. * imapx_command_queue() now takes a GCancellable and GError argument and returns a 'success' boolean. Other core job and command routing functions also now have similar function signatures. * Add error handling where needed, so that no failable function call goes unchecked. --- diff --git a/camel/camel-imapx-command.h b/camel/camel-imapx-command.h index b1dff50..ac9e77b 100644 --- a/camel/camel-imapx-command.h +++ b/camel/camel-imapx-command.h @@ -40,6 +40,7 @@ typedef struct _CamelIMAPXCommandPart CamelIMAPXCommandPart; typedef gboolean (*CamelIMAPXCommandFunc) (struct _CamelIMAPXServer *is, CamelIMAPXCommand *ic, + GCancellable *cancellable, GError **error); typedef enum { diff --git a/camel/camel-imapx-job.c b/camel/camel-imapx-job.c index c8fc68a..18c7136 100644 --- a/camel/camel-imapx-job.c +++ b/camel/camel-imapx-job.c @@ -28,6 +28,8 @@ struct _CamelIMAPXRealJob { volatile gint ref_count; + GCancellable *cancellable; + /* Used for running some jobs synchronously. */ GCond *done_cond; GMutex *done_mutex; @@ -55,9 +57,6 @@ camel_imapx_job_new (GCancellable *cancellable) { CamelIMAPXRealJob *real_job; - if (cancellable != NULL) - g_object_ref (cancellable); - real_job = g_slice_new0 (CamelIMAPXRealJob); /* Initialize private bits. */ @@ -65,8 +64,9 @@ camel_imapx_job_new (GCancellable *cancellable) real_job->done_cond = g_cond_new (); real_job->done_mutex = g_mutex_new (); - /* Initialize public bits. */ - real_job->public.cancellable = cancellable; + if (cancellable != NULL) + g_object_ref (cancellable); + real_job->cancellable = cancellable; return (CamelIMAPXJob *) real_job; } @@ -98,14 +98,11 @@ camel_imapx_job_unref (CamelIMAPXJob *job) /* Free the public stuff. */ - g_clear_error (&real_job->public.error); - if (real_job->public.pop_operation_msg) - camel_operation_pop_message ( - real_job->public.cancellable); + camel_operation_pop_message (real_job->cancellable); - if (real_job->public.cancellable != NULL) - g_object_unref (real_job->public.cancellable); + if (real_job->cancellable != NULL) + g_object_unref (real_job->cancellable); /* Free the private stuff. */ @@ -139,6 +136,18 @@ camel_imapx_job_check (CamelIMAPXJob *job) } void +camel_imapx_job_cancel (CamelIMAPXJob *job) +{ + CamelIMAPXRealJob *real_job; + + g_return_if_fail (CAMEL_IS_IMAPX_JOB (job)); + + real_job = (CamelIMAPXRealJob *) job; + + g_cancellable_cancel (real_job->cancellable); +} + +void camel_imapx_job_wait (CamelIMAPXJob *job) { CamelIMAPXRealJob *real_job; @@ -175,40 +184,35 @@ camel_imapx_job_run (CamelIMAPXJob *job, CamelIMAPXServer *is, GError **error) { + GCancellable *cancellable; gulong cancel_id = 0; + gboolean success; g_return_val_if_fail (CAMEL_IS_IMAPX_JOB (job), FALSE); g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (is), FALSE); g_return_val_if_fail (job->start != NULL, FALSE); - if (g_cancellable_set_error_if_cancelled (job->cancellable, error)) + cancellable = ((CamelIMAPXRealJob *) job)->cancellable; + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) return FALSE; - if (G_IS_CANCELLABLE (job->cancellable)) + if (G_IS_CANCELLABLE (cancellable)) cancel_id = g_cancellable_connect ( - job->cancellable, + cancellable, G_CALLBACK (imapx_job_cancelled_cb), camel_imapx_job_ref (job), (GDestroyNotify) camel_imapx_job_unref); - job->start (job, is); + success = job->start (job, is, cancellable, error); - if (!job->noreply) + if (success && !job->noreply) camel_imapx_job_wait (job); if (cancel_id > 0) - g_cancellable_disconnect (job->cancellable, cancel_id); - - if (g_cancellable_set_error_if_cancelled (job->cancellable, error)) - return FALSE; - - if (job->error != NULL) { - g_propagate_error (error, job->error); - job->error = NULL; - return FALSE; - } + g_cancellable_disconnect (cancellable, cancel_id); - return TRUE; + return success; } gboolean diff --git a/camel/camel-imapx-job.h b/camel/camel-imapx-job.h index aababec..160eac2 100644 --- a/camel/camel-imapx-job.h +++ b/camel/camel-imapx-job.h @@ -40,15 +40,14 @@ struct _uidset_state { }; struct _CamelIMAPXJob { - GCancellable *cancellable; - GError *error; - /* Whether to pop a status message off the * GCancellable when the job is finalized. */ gboolean pop_operation_msg; - void (*start) (CamelIMAPXJob *job, - CamelIMAPXServer *is); + gboolean (*start) (CamelIMAPXJob *job, + CamelIMAPXServer *is, + GCancellable *cancellable, + GError **error); gboolean (*matches) (CamelIMAPXJob *job, CamelFolder *folder, const gchar *uid); @@ -65,6 +64,7 @@ CamelIMAPXJob * camel_imapx_job_new (GCancellable *cancellable); CamelIMAPXJob * camel_imapx_job_ref (CamelIMAPXJob *job); void camel_imapx_job_unref (CamelIMAPXJob *job); gboolean camel_imapx_job_check (CamelIMAPXJob *job); +void camel_imapx_job_cancel (CamelIMAPXJob *job); void camel_imapx_job_wait (CamelIMAPXJob *job); void camel_imapx_job_done (CamelIMAPXJob *job); gboolean camel_imapx_job_run (CamelIMAPXJob *job, diff --git a/camel/camel-imapx-server.c b/camel/camel-imapx-server.c index 8a97e7e..c15e53f 100644 --- a/camel/camel-imapx-server.c +++ b/camel/camel-imapx-server.c @@ -403,9 +403,11 @@ static CamelIMAPXJob * imapx_match_active_job (CamelIMAPXServer *is, guint32 type, const gchar *uid); -static void imapx_job_fetch_new_messages_start +static gboolean imapx_job_fetch_new_messages_start (CamelIMAPXJob *job, - CamelIMAPXServer *is); + CamelIMAPXServer *is, + GCancellable *cancellable, + GError **error); static gint imapx_refresh_info_uid_cmp (gconstpointer ap, gconstpointer bp, gboolean ascending); @@ -418,10 +420,12 @@ static gboolean imapx_server_sync_changes (CamelIMAPXServer *is, GError **error); static void imapx_sync_free_user (GArray *user_set); -static void imapx_command_copy_messages_step_start +static gboolean imapx_command_copy_messages_step_start (CamelIMAPXServer *is, CamelIMAPXJob *job, - gint index); + gint index, + GCancellable *cancellable, + GError **error); enum _idle_state { IMAPX_IDLE_OFF, @@ -835,7 +839,7 @@ err: * GError to get here, and we're not interested * in individual command errors. */ if (ic != NULL && ic->complete != NULL) - ic->complete (is, ic, NULL); + ic->complete (is, ic, NULL, NULL); exit: if (stream != NULL) @@ -1160,17 +1164,20 @@ imapx_is_command_queue_empty (CamelIMAPXServer *is) return TRUE; } -static void +static gboolean imapx_command_queue (CamelIMAPXServer *is, - CamelIMAPXCommand *ic) + CamelIMAPXCommand *ic, + GCancellable *cancellable, + GError **error) { CamelIMAPXJob *job; + gboolean success; /* We enqueue in priority order, new messages have * higher priority than older messages with the same priority */ job = camel_imapx_command_get_job (ic); - g_return_if_fail (CAMEL_IS_IMAPX_JOB (job)); + g_return_val_if_fail (CAMEL_IS_IMAPX_JOB (job), FALSE); camel_imapx_command_close (ic); @@ -1180,28 +1187,28 @@ imapx_command_queue (CamelIMAPXServer *is, if (is->state == IMAPX_SHUTDOWN) { c (is->tagprefix, "refuse to queue job on disconnected server\n"); - if (job->error == NULL) - g_set_error ( - &job->error, CAMEL_IMAPX_ERROR, 1, - "%s", _("Server disconnected")); + g_set_error ( + error, CAMEL_IMAPX_ERROR, 1, + "%s", _("Server disconnected")); + QUEUE_UNLOCK (is); - /* Send a NULL GError since we've already set - * the job's GError, and we're not interested - * in individual command errors. */ + /* Send a NULL GError since we've already set the + * GError, and we're not interested in individual + * command errors at this point. */ if (ic->complete != NULL) - ic->complete (is, ic, NULL); - return; + ic->complete (is, ic, NULL, NULL); + + return FALSE; } camel_imapx_command_queue_insert_sorted (is->queue, ic); - /* XXX No error checking. We don't care if this fails? */ - imapx_command_start_next (is, job->cancellable, NULL); + success = imapx_command_start_next (is, cancellable, error); QUEUE_UNLOCK (is); - return; + return success; } /* Must have QUEUE lock */ @@ -1636,17 +1643,20 @@ imapx_untagged_fetch (CamelIMAPXServer *is, /* This must've been a get-message request, fill out the body stream, * in the right spot */ - if (job && job->error == NULL) { + if (job != NULL) { if (data->use_multi_fetch) { data->body_offset = finfo->offset; g_seekable_seek (G_SEEKABLE (data->stream), finfo->offset, G_SEEK_SET, NULL, NULL); } - data->body_len = camel_stream_write_to_stream (finfo->body, data->stream, job->cancellable, &job->error); - if (data->body_len == -1) + data->body_len = camel_stream_write_to_stream ( + finfo->body, data->stream, cancellable, error); + if (data->body_len == -1) { g_prefix_error ( - &job->error, - _("Error writing to cache stream: ")); + error, "%s: ", + _("Error writing to cache stream")); + return FALSE; + } } } @@ -1830,7 +1840,7 @@ imapx_untagged_fetch (CamelIMAPXServer *is, } cnt = (camel_folder_summary_count (job->folder->summary) * 100 ) / ifolder->exists_on_server; - camel_operation_progress (job->cancellable, cnt ? cnt : 1); + camel_operation_progress (cancellable, cnt ? cnt : 1); } else { camel_message_info_free (mi); } @@ -2472,7 +2482,7 @@ imapx_completion (CamelIMAPXServer *is, return FALSE; if (ic->complete != NULL) - if (!ic->complete (is, ic, error)) + if (!ic->complete (is, ic, cancellable, error)) return FALSE; QUEUE_LOCK (is); @@ -2561,6 +2571,7 @@ imapx_command_run (CamelIMAPXServer *is, static gboolean imapx_command_complete (CamelIMAPXServer *is, CamelIMAPXCommand *ic, + GCancellable *cancellable, GError **error) { camel_imapx_command_done (ic); @@ -2589,6 +2600,7 @@ imapx_command_run_sync (CamelIMAPXServer *is, GError **error) { guint cancel_id = 0; + gboolean success; /* FIXME The only caller of this function currently does not set * a "complete" callback function, so we can get away with @@ -2611,20 +2623,18 @@ imapx_command_run_sync (CamelIMAPXServer *is, /* Unref'ed in imapx_command_complete(). */ camel_imapx_command_ref (ic); - imapx_command_queue (is, ic); + success = imapx_command_queue (is, ic, cancellable, error); - camel_imapx_command_wait (ic); + if (success) + camel_imapx_command_wait (ic); if (cancel_id > 0) g_cancellable_disconnect (cancellable, cancel_id); - if (g_cancellable_set_error_if_cancelled (cancellable, error)) - return FALSE; - if (camel_imapx_command_set_error_if_failed (ic, error)) return FALSE; - return TRUE; + return success; } static gboolean @@ -2707,6 +2717,7 @@ imapx_command_idle_stop (CamelIMAPXServer *is, static gboolean imapx_command_idle_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic, + GCancellable *cancellable, GError **error) { CamelIMAPXIdle *idle = is->idle; @@ -2733,12 +2744,15 @@ imapx_command_idle_done (CamelIMAPXServer *is, return success; } -static void +static gboolean imapx_job_idle_start (CamelIMAPXJob *job, - CamelIMAPXServer *is) + CamelIMAPXServer *is, + GCancellable *cancellable, + GError **error) { CamelIMAPXCommand *ic; CamelIMAPXCommandPart *cp; + gboolean success = TRUE; ic = camel_imapx_command_new ( is, "IDLE", job->folder, "IDLE"); @@ -2755,13 +2769,15 @@ imapx_job_idle_start (CamelIMAPXJob *job, /* Don't issue it if the idle was cancelled already */ if (is->idle->state == IMAPX_IDLE_PENDING) { is->idle->state = IMAPX_IDLE_ISSUED; - imapx_command_start (is, ic, job->cancellable, &job->error); + success = imapx_command_start (is, ic, cancellable, error); } else { imapx_unregister_job (is, job); camel_imapx_command_unref (ic); } IDLE_UNLOCK (is->idle); QUEUE_UNLOCK (is); + + return success; } static gboolean @@ -3041,6 +3057,7 @@ imapx_idle_supported (CamelIMAPXServer *is) static gboolean imapx_command_select_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic, + GCancellable *cancellable, GError **error) { const gchar *selected_folder = NULL; @@ -3091,20 +3108,12 @@ imapx_command_select_done (CamelIMAPXServer *is, continue; } + camel_imapx_job_cancel (job); + if (ic->status) cw->status = imapx_copy_status (ic->status); - if (job->error == NULL) { - if (ic->status == NULL) - /* FIXME: why is ic->status == NULL here? It shouldn't happen. */ - g_debug ("imapx_command_select_done: ic->status is NULL."); - g_set_error ( - &job->error, - CAMEL_IMAPX_ERROR, 1, - "SELECT %s failed: %s", - camel_folder_get_full_name (cw->select), - ic->status && ic->status->text? ic->status->text:""); - } - cw->complete (is, cw, NULL); + + cw->complete (is, cw, NULL, NULL); } if (is->select_pending) @@ -3958,6 +3967,7 @@ exit: static gboolean imapx_command_fetch_message_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic, + GCancellable *cancellable, GError **error) { CamelIMAPXJob *job; @@ -3993,9 +4003,10 @@ imapx_command_fetch_message_done (CamelIMAPXServer *is, if (data->fetch_offset < data->size || data->fetch_offset == really_fetched) { CamelIMAPXCommand *new_ic; + gboolean success; camel_operation_progress ( - job->cancellable, + cancellable, (data->fetch_offset *100) / data->size); new_ic = camel_imapx_command_new ( @@ -4009,11 +4020,13 @@ imapx_command_fetch_message_done (CamelIMAPXServer *is, new_ic->pri = job->pri - 1; data->fetch_offset += MULTI_SIZE; job->commands++; - imapx_command_queue (is, new_ic); + + success = imapx_command_queue ( + is, new_ic, cancellable, error); camel_imapx_command_unref (ic); - return TRUE; + return success; } } @@ -4039,9 +4052,9 @@ imapx_command_fetch_message_done (CamelIMAPXServer *is, } else if (data->stream != NULL) { success = (camel_stream_flush ( - data->stream, job->cancellable, &job->error) == 0) && + data->stream, cancellable, error) == 0) && (camel_stream_close ( - data->stream, job->cancellable, &job->error) == 0); + data->stream, cancellable, error) == 0); if (success) { gchar *cur_filename; @@ -4060,7 +4073,7 @@ imapx_command_fetch_message_done (CamelIMAPXServer *is, if (g_rename (tmp_filename, cur_filename) != 0) g_set_error ( - &job->error, G_FILE_ERROR, + error, G_FILE_ERROR, g_file_error_from_errno (errno), "%s: %s", _("Failed to copy the tmp file"), @@ -4072,11 +4085,11 @@ imapx_command_fetch_message_done (CamelIMAPXServer *is, /* Exchange the "tmp" stream for the "cur" stream. */ g_object_unref (data->stream); data->stream = camel_data_cache_get ( - ifolder->cache, "cur", data->uid, &job->error); + ifolder->cache, "cur", data->uid, error); success = (data->stream != NULL); } else { g_prefix_error ( - &job->error, "%s: ", + error, "%s: ", _("Failed to close the tmp stream")); } } @@ -4092,16 +4105,19 @@ exit: return success; } -static void +static gboolean imapx_job_get_message_start (CamelIMAPXJob *job, - CamelIMAPXServer *is) + CamelIMAPXServer *is, + GCancellable *cancellable, + GError **error) { CamelIMAPXCommand *ic; GetMessageData *data; gint i; + gboolean success = TRUE; data = camel_imapx_job_get_data (job); - g_return_if_fail (data != NULL); + g_return_val_if_fail (data != NULL, FALSE); if (data->use_multi_fetch) { for (i = 0; i < 3 && data->fetch_offset < data->size; i++) { @@ -4116,7 +4132,11 @@ imapx_job_get_message_start (CamelIMAPXJob *job, ic->pri = job->pri; data->fetch_offset += MULTI_SIZE; job->commands++; - imapx_command_queue (is, ic); + + success = imapx_command_queue ( + is, ic, cancellable, error); + if (!success) + break; } } else { ic = camel_imapx_command_new ( @@ -4127,8 +4147,11 @@ imapx_job_get_message_start (CamelIMAPXJob *job, camel_imapx_command_set_job (ic, job); ic->pri = job->pri; job->commands++; - imapx_command_queue (is, ic); + + success = imapx_command_queue (is, ic, cancellable, error); } + + return success; } static gboolean @@ -4155,6 +4178,7 @@ imapx_job_get_message_matches (CamelIMAPXJob *job, static gboolean imapx_command_copy_messages_step_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic, + GCancellable *cancellable, GError **error) { CamelIMAPXJob *job; @@ -4174,7 +4198,7 @@ imapx_command_copy_messages_step_done (CamelIMAPXServer *is, if (camel_imapx_command_set_error_if_failed (ic, error)) { g_prefix_error ( - &job->error, "%s: ", + error, "%s: ", _("Error copying messages")); success = FALSE; goto cleanup; @@ -4203,8 +4227,9 @@ imapx_command_copy_messages_step_done (CamelIMAPXServer *is, if (i < uids->len) { camel_imapx_command_unref (ic); - imapx_command_copy_messages_step_start (is, job, i); - return TRUE; + + return imapx_command_copy_messages_step_start ( + is, job, i, cancellable, error); } cleanup: @@ -4216,10 +4241,12 @@ cleanup: return success; } -static void +static gboolean imapx_command_copy_messages_step_start (CamelIMAPXServer *is, CamelIMAPXJob *job, - gint index) + gint index, + GCancellable *cancellable, + GError **error) { CamelIMAPXCommand *ic; CopyMessagesData *data; @@ -4227,7 +4254,7 @@ imapx_command_copy_messages_step_start (CamelIMAPXServer *is, gint i = index; data = camel_imapx_job_get_data (job); - g_return_if_fail (data != NULL); + g_return_val_if_fail (data != NULL, FALSE); uids = data->uids; @@ -4246,35 +4273,42 @@ imapx_command_copy_messages_step_start (CamelIMAPXServer *is, if (res == 1) { camel_imapx_command_add (ic, " %f", data->dest); data->index = i + 1; - imapx_command_queue (is, ic); - return; + return imapx_command_queue (is, ic, cancellable, error); } } data->index = i; if (imapx_uidset_done (&data->uidset, ic)) { camel_imapx_command_add (ic, " %f", data->dest); - imapx_command_queue (is, ic); - return; + return imapx_command_queue (is, ic, cancellable, error); } + + return TRUE; } -static void +static gboolean imapx_job_copy_messages_start (CamelIMAPXJob *job, - CamelIMAPXServer *is) + CamelIMAPXServer *is, + GCancellable *cancellable, + GError **error) { CopyMessagesData *data; + gboolean success; data = camel_imapx_job_get_data (job); - g_return_if_fail (data != NULL); + g_return_val_if_fail (data != NULL, FALSE); - if (!imapx_server_sync_changes ( - is, job->folder, job->pri, job->cancellable, &job->error)) + success = imapx_server_sync_changes ( + is, job->folder, job->pri, cancellable, error); + if (!success) imapx_unregister_job (is, job); + /* XXX Should we still do this even if a failure occurred? */ g_ptr_array_sort (data->uids, (GCompareFunc) imapx_uids_array_cmp); imapx_uidset_init (&data->uidset, 0, MAX_COMMAND_LEN); - imapx_command_copy_messages_step_start (is, job, 0); + + return imapx_command_copy_messages_step_start ( + is, job, 0, cancellable, error); } /* ********************************************************************** */ @@ -4282,6 +4316,7 @@ imapx_job_copy_messages_start (CamelIMAPXJob *job, static gboolean imapx_command_append_message_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic, + GCancellable *cancellable, GError **error) { CamelIMAPXJob *job; @@ -4351,15 +4386,17 @@ imapx_command_append_message_done (CamelIMAPXServer *is, return success; } -static void +static gboolean imapx_job_append_message_start (CamelIMAPXJob *job, - CamelIMAPXServer *is) + CamelIMAPXServer *is, + GCancellable *cancellable, + GError **error) { CamelIMAPXCommand *ic; AppendMessageData *data; data = camel_imapx_job_get_data (job); - g_return_if_fail (data != NULL); + g_return_val_if_fail (data != NULL, FALSE); /* TODO: we could supply the original append date from the file timestamp */ ic = camel_imapx_command_new ( @@ -4372,7 +4409,8 @@ imapx_job_append_message_start (CamelIMAPXJob *job, camel_imapx_command_set_job (ic, job); ic->pri = job->pri; job->commands++; - imapx_command_queue (is, ic); + + return imapx_command_queue (is, ic, cancellable, error); } /* ********************************************************************** */ @@ -4459,6 +4497,7 @@ imapx_index_next (GPtrArray *uids, static gboolean imapx_command_step_fetch_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic, + GCancellable *cancellable, GError **error) { CamelIMAPXFolder *ifolder; @@ -4534,8 +4573,8 @@ imapx_command_step_fetch_done (CamelIMAPXServer *is, if (res == 1) { camel_imapx_command_add (ic, " (RFC822.SIZE RFC822.HEADER)"); data->index = i + 1; - imapx_command_queue (is, ic); - return TRUE; + + return imapx_command_queue (is, ic, cancellable, error); } } } @@ -4545,8 +4584,7 @@ imapx_command_step_fetch_done (CamelIMAPXServer *is, if (imapx_uidset_done (&data->uidset, ic)) { camel_imapx_command_add (ic, " (RFC822.SIZE RFC822.HEADER)"); - imapx_command_queue (is, ic); - return TRUE; + return imapx_command_queue (is, ic, cancellable, error); } } @@ -4605,6 +4643,7 @@ imapx_uid_cmp (gconstpointer ap, static gboolean imapx_job_scan_changes_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic, + GCancellable *cancellable, GError **error) { CamelIMAPXJob *job; @@ -4751,7 +4790,7 @@ imapx_job_scan_changes_done (CamelIMAPXServer *is, job->pop_operation_msg = TRUE; camel_operation_push_message ( - job->cancellable, + cancellable, _("Fetching summary information for new messages in '%s'"), camel_folder_get_display_name (job->folder)); @@ -4759,7 +4798,9 @@ imapx_job_scan_changes_done (CamelIMAPXServer *is, /* These are new messages which arrived since we last knew the unseen count; * update it as they arrive. */ data->update_unseen = TRUE; - return imapx_command_step_fetch_done (is, ic, error); + + return imapx_command_step_fetch_done ( + is, ic, cancellable, error); } } @@ -4779,9 +4820,11 @@ imapx_job_scan_changes_done (CamelIMAPXServer *is, return success; } -static void +static gboolean imapx_job_scan_changes_start (CamelIMAPXJob *job, - CamelIMAPXServer *is) + CamelIMAPXServer *is, + GCancellable *cancellable, + GError **error) { CamelIMAPXCommand *ic; RefreshInfoData *data; @@ -4797,12 +4840,12 @@ imapx_job_scan_changes_start (CamelIMAPXJob *job, uid = imapx_get_uid_from_index (job->folder->summary, 0); data = camel_imapx_job_get_data (job); - g_return_if_fail (data != NULL); + g_return_val_if_fail (data != NULL, FALSE); job->pop_operation_msg = TRUE; camel_operation_push_message ( - job->cancellable, + cancellable, _("Scanning for changed messages in '%s'"), camel_folder_get_display_name (job->folder)); @@ -4820,13 +4863,16 @@ imapx_job_scan_changes_start (CamelIMAPXJob *job, ic->pri = job->pri; refresh_info_data_infos_free (data); data->infos = g_array_new (0, 0, sizeof (struct _refresh_info)); - imapx_command_queue (is, ic); + g_free (uid); + + return imapx_command_queue (is, ic, cancellable, error); } static gboolean imapx_command_fetch_new_messages_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic, + GCancellable *cancellable, GError **error) { CamelIMAPXJob *job; @@ -4888,6 +4934,7 @@ exception: static gboolean imapx_command_fetch_new_uids_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic, + GCancellable *cancellable, GError **error) { CamelIMAPXJob *job; @@ -4907,12 +4954,14 @@ imapx_command_fetch_new_uids_done (CamelIMAPXServer *is, sizeof (struct _refresh_info), imapx_refresh_info_cmp_descending); - return imapx_command_step_fetch_done (is, ic, error); + return imapx_command_step_fetch_done (is, ic, cancellable, error); } -static void +static gboolean imapx_job_fetch_new_messages_start (CamelIMAPXJob *job, - CamelIMAPXServer *is) + CamelIMAPXServer *is, + GCancellable *cancellable, + GError **error) { CamelIMAPXCommand *ic; CamelFolder *folder = job->folder; @@ -4925,7 +4974,7 @@ imapx_job_fetch_new_messages_start (CamelIMAPXJob *job, gchar *uid = NULL; data = camel_imapx_job_get_data (job); - g_return_if_fail (data != NULL); + g_return_val_if_fail (data != NULL, FALSE); settings = camel_imapx_server_ref_settings (is); fetch_order = camel_imapx_settings_get_fetch_order (settings); @@ -4947,7 +4996,7 @@ imapx_job_fetch_new_messages_start (CamelIMAPXJob *job, job->pop_operation_msg = TRUE; camel_operation_push_message ( - job->cancellable, + cancellable, _("Fetching summary information for new messages in '%s'"), camel_folder_get_display_name (folder)); @@ -4976,13 +5025,17 @@ imapx_job_fetch_new_messages_start (CamelIMAPXJob *job, } g_free (uid); + camel_imapx_command_set_job (ic, job); - imapx_command_queue (is, ic); + + return imapx_command_queue (is, ic, cancellable, error); } -static void +static gboolean imapx_job_fetch_messages_start (CamelIMAPXJob *job, - CamelIMAPXServer *is) + CamelIMAPXServer *is, + GCancellable *cancellable, + GError **error) { CamelIMAPXCommand *ic; CamelFolder *folder = job->folder; @@ -4996,7 +5049,7 @@ imapx_job_fetch_messages_start (CamelIMAPXJob *job, RefreshInfoData *data; data = camel_imapx_job_get_data (job); - g_return_if_fail (data != NULL); + g_return_val_if_fail (data != NULL, FALSE); settings = camel_imapx_server_ref_settings (is); fetch_order = camel_imapx_settings_get_fetch_order (settings); @@ -5024,6 +5077,8 @@ imapx_job_fetch_messages_start (CamelIMAPXJob *job, } if (ftype == CAMEL_FETCH_NEW_MESSAGES) { + gboolean success; + /* We need to issue Status command to get the total unread count */ ic = camel_imapx_command_new ( is, "STATUS", NULL, @@ -5031,22 +5086,21 @@ imapx_job_fetch_messages_start (CamelIMAPXJob *job, camel_imapx_command_set_job (ic, job); ic->pri = job->pri; - imapx_command_run_sync (is, ic, job->cancellable, &job->error); + success = imapx_command_run_sync ( + is, ic, cancellable, error); - job = camel_imapx_command_get_job (ic); - g_return_if_fail (CAMEL_IS_IMAPX_JOB (job)); + camel_imapx_command_unref (ic); - if (job->error != NULL || camel_imapx_command_set_error_if_failed (ic, &job->error)) { + if (!success) { g_prefix_error ( - &job->error, "%s: ", + error, "%s: ", _("Error while fetching messages")); + return FALSE; } - - camel_imapx_command_unref (ic); } camel_operation_push_message ( - job->cancellable, ngettext ( + cancellable, ngettext ( "Fetching summary information for %d message in '%s'", "Fetching summary information for %d messages in '%s'", data->fetch_msg_limit), @@ -5072,9 +5126,6 @@ imapx_job_fetch_messages_start (CamelIMAPXJob *job, g_free (uid); - camel_imapx_command_set_job (ic, job); - imapx_command_queue (is, ic); - } else if (ftype == CAMEL_FETCH_OLD_MESSAGES && total > 0) { guint64 uidl; start_uid = imapx_get_uid_from_index (folder->summary, 0); @@ -5082,7 +5133,7 @@ imapx_job_fetch_messages_start (CamelIMAPXJob *job, end_uid = g_strdup_printf ("%" G_GINT64_MODIFIER "d", (((gint) uidl) - fetch_limit > 0) ? (uidl - fetch_limit) : 1); camel_operation_push_message ( - job->cancellable, ngettext ( + cancellable, ngettext ( "Fetching summary information for %d message in '%s'", "Fetching summary information for %d messages in '%s'", data->fetch_msg_limit), @@ -5098,17 +5149,20 @@ imapx_job_fetch_messages_start (CamelIMAPXJob *job, g_free (start_uid); g_free (end_uid); - camel_imapx_command_set_job (ic, job); - imapx_command_queue (is, ic); - } else { g_error ("Shouldn't reach here. Incorrect fetch type"); } + + camel_imapx_command_set_job (ic, job); + + return imapx_command_queue (is, ic, cancellable, error); } -static void +static gboolean imapx_job_refresh_info_start (CamelIMAPXJob *job, - CamelIMAPXServer *is) + CamelIMAPXServer *is, + GCancellable *cancellable, + GError **error) { guint32 total; CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *) job->folder; @@ -5120,6 +5174,7 @@ imapx_job_refresh_info_start (CamelIMAPXJob *job, gboolean can_qresync = FALSE; CamelIMAPXSettings *settings; gboolean mobile_mode; + gboolean success; settings = camel_imapx_server_ref_settings (is); mobile_mode = camel_imapx_settings_get_mobile_mode (settings); @@ -5129,9 +5184,9 @@ imapx_job_refresh_info_start (CamelIMAPXJob *job, /* Sync changes first, else unread count will not * match. Need to think about better ways for this */ - if (!imapx_server_sync_changes ( - is, folder, job->pri, - job->cancellable, &job->error)) + success = imapx_server_sync_changes ( + is, folder, job->pri, cancellable, error); + if (!success) goto done; #if 0 /* There are issues with this still; continue with the buggy @@ -5171,17 +5226,16 @@ imapx_job_refresh_info_start (CamelIMAPXJob *job, /* We may not issue STATUS on the current folder. Use SELECT or NOOP instead. */ if (0 /* server needs SELECT not just NOOP */) { if (imapx_idle_supported (is) && imapx_in_idle (is)) - if (!imapx_stop_idle (is, &job->error)) + if (!imapx_stop_idle (is, error)) goto done; /* This doesn't work -- this is an immediate command, not queued */ if (!imapx_select ( - is, folder, TRUE, - job->cancellable, &job->error)) + is, folder, TRUE, cancellable, error)) goto done; } else { /* Or maybe just NOOP, unless we're in IDLE in which case do nothing */ if (!imapx_idle_supported (is) || !imapx_in_idle (is)) { - if (!camel_imapx_server_noop (is, folder, job->cancellable, &job->error)) + if (!camel_imapx_server_noop (is, folder, cancellable, error)) goto done; } } @@ -5200,24 +5254,17 @@ imapx_job_refresh_info_start (CamelIMAPXJob *job, camel_imapx_command_set_job (ic, job); ic->pri = job->pri; - imapx_command_run_sync ( - is, ic, job->cancellable, &job->error); + success = imapx_command_run_sync ( + is, ic, cancellable, error); - job = camel_imapx_command_get_job (ic); - g_return_if_fail (CAMEL_IS_IMAPX_JOB (job)); + camel_imapx_command_unref (ic); - if (job->error != NULL || camel_imapx_command_set_error_if_failed (ic, &job->error)) { + if (!success) { g_prefix_error ( - &job->error, "%s: ", + error, "%s: ", _("Error refreshing folder")); - } - - if (job->error != NULL) { - camel_imapx_command_unref (ic); goto done; } - - camel_imapx_command_unref (ic); } /* Recalulate need_rescan */ @@ -5237,22 +5284,17 @@ imapx_job_refresh_info_start (CamelIMAPXJob *job, camel_imapx_command_set_job (ic, job); ic->pri = job->pri; - imapx_command_run_sync (is, ic, job->cancellable, &job->error); + success = imapx_command_run_sync ( + is, ic, cancellable, error); - job = camel_imapx_command_get_job (ic); - g_return_if_fail (CAMEL_IS_IMAPX_JOB (job)); + camel_imapx_command_unref (ic); - if (job->error != NULL || camel_imapx_command_set_error_if_failed (ic, &job->error)) { + if (!success) { g_prefix_error ( - &job->error, "%s: ", + error, "%s: ", _("Error refreshing folder")); - } - - if (job->error != NULL) { - camel_imapx_command_unref (ic); goto done; } - camel_imapx_command_unref (ic); } if (is->use_qresync && isum->modseq && ifolder->uidvalidity_on_server) @@ -5273,9 +5315,9 @@ imapx_job_refresh_info_start (CamelIMAPXJob *job, if (!total) need_rescan = FALSE; - if (!imapx_server_fetch_new_messages ( - is, folder, FALSE, FALSE, - job->cancellable, &job->error)) + success = imapx_server_fetch_new_messages ( + is, folder, FALSE, FALSE, cancellable, error); + if (!success) goto done; /* If QRESYNC-capable we'll have got all flags changes in SELECT */ @@ -5288,7 +5330,10 @@ imapx_job_refresh_info_start (CamelIMAPXJob *job, if (can_qresync) { /* Actually we only want to select it; no need for the NOOP */ - camel_imapx_server_noop (is, folder, job->cancellable, &job->error); + success = camel_imapx_server_noop ( + is, folder, cancellable, error); + if (!success) + goto done; qresync_done: isum->modseq = ifolder->modseq_on_server; total = camel_folder_summary_count (job->folder->summary); @@ -5310,11 +5355,12 @@ imapx_job_refresh_info_start (CamelIMAPXJob *job, } } - imapx_job_scan_changes_start (job, is); - return; + return imapx_job_scan_changes_start (job, is, cancellable, error); done: imapx_unregister_job (is, job); + + return success; } static gboolean @@ -5330,6 +5376,7 @@ imapx_job_refresh_info_matches (CamelIMAPXJob *job, static gboolean imapx_command_expunge_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic, + GCancellable *cancellable, GError **error) { CamelIMAPXJob *job; @@ -5354,7 +5401,7 @@ imapx_command_expunge_done (CamelIMAPXServer *is, parent_store = camel_folder_get_parent_store (folder); camel_folder_summary_save_to_db (folder->summary, NULL); - uids = camel_db_get_folder_deleted_uids (parent_store->cdb_r, full_name, &job->error); + uids = camel_db_get_folder_deleted_uids (parent_store->cdb_r, full_name, error); if (uids && uids->len) { CamelFolderChangeInfo *changes; @@ -5394,24 +5441,30 @@ imapx_command_expunge_done (CamelIMAPXServer *is, return success; } -static void +static gboolean imapx_job_expunge_start (CamelIMAPXJob *job, - CamelIMAPXServer *is) + CamelIMAPXServer *is, + GCancellable *cancellable, + GError **error) { CamelIMAPXCommand *ic; + gboolean success; - imapx_server_sync_changes ( - is, job->folder, job->pri, - job->cancellable, &job->error); + success = imapx_server_sync_changes ( + is, job->folder, job->pri, cancellable, error); - /* TODO handle UIDPLUS capability */ - ic = camel_imapx_command_new ( - is, "EXPUNGE", job->folder, "EXPUNGE"); - camel_imapx_command_set_job (ic, job); - ic->pri = job->pri; - ic->complete = imapx_command_expunge_done; + if (success) { + /* TODO handle UIDPLUS capability */ + ic = camel_imapx_command_new ( + is, "EXPUNGE", job->folder, "EXPUNGE"); + camel_imapx_command_set_job (ic, job); + ic->pri = job->pri; + ic->complete = imapx_command_expunge_done; + + success = imapx_command_queue (is, ic, cancellable, error); + } - imapx_command_queue (is, ic); + return success; } static gboolean @@ -5427,6 +5480,7 @@ imapx_job_expunge_matches (CamelIMAPXJob *job, static gboolean imapx_command_list_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic, + GCancellable *cancellable, GError **error) { CamelIMAPXJob *job; @@ -5449,15 +5503,17 @@ imapx_command_list_done (CamelIMAPXServer *is, return success; } -static void +static gboolean imapx_job_list_start (CamelIMAPXJob *job, - CamelIMAPXServer *is) + CamelIMAPXServer *is, + GCancellable *cancellable, + GError **error) { CamelIMAPXCommand *ic; ListData *data; data = camel_imapx_job_get_data (job); - g_return_if_fail (data != NULL); + g_return_val_if_fail (data != NULL, FALSE); ic = camel_imapx_command_new ( is, "LIST", NULL, @@ -5474,7 +5530,7 @@ imapx_job_list_start (CamelIMAPXJob *job, camel_imapx_command_set_job (ic, job); ic->complete = imapx_command_list_done; - imapx_command_queue (is, ic); + return imapx_command_queue (is, ic, cancellable, error); } static gboolean @@ -5506,6 +5562,7 @@ imapx_encode_folder_name (CamelIMAPXStore *istore, static gboolean imapx_command_subscription_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic, + GCancellable *cancellable, GError **error) { CamelIMAPXJob *job; @@ -5527,9 +5584,11 @@ imapx_command_subscription_done (CamelIMAPXServer *is, return success; } -static void +static gboolean imapx_job_manage_subscription_start (CamelIMAPXJob *job, - CamelIMAPXServer *is) + CamelIMAPXServer *is, + GCancellable *cancellable, + GError **error) { CamelIMAPXCommand *ic; CamelIMAPXStore *store; @@ -5537,7 +5596,7 @@ imapx_job_manage_subscription_start (CamelIMAPXJob *job, gchar *encoded_fname = NULL; data = camel_imapx_job_get_data (job); - g_return_if_fail (data != NULL); + g_return_val_if_fail (data != NULL, FALSE); store = camel_imapx_server_ref_store (is); @@ -5555,11 +5614,12 @@ imapx_job_manage_subscription_start (CamelIMAPXJob *job, ic->pri = job->pri; camel_imapx_command_set_job (ic, job); ic->complete = imapx_command_subscription_done; - imapx_command_queue (is, ic); g_free (encoded_fname); g_object_unref (store); + + return imapx_command_queue (is, ic, cancellable, error); } /* ********************************************************************** */ @@ -5567,6 +5627,7 @@ imapx_job_manage_subscription_start (CamelIMAPXJob *job, static gboolean imapx_command_create_folder_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic, + GCancellable *cancellable, GError **error) { CamelIMAPXJob *job; @@ -5588,27 +5649,31 @@ imapx_command_create_folder_done (CamelIMAPXServer *is, return success; } -static void +static gboolean imapx_job_create_folder_start (CamelIMAPXJob *job, - CamelIMAPXServer *is) + CamelIMAPXServer *is, + GCancellable *cancellable, + GError **error) { CamelIMAPXCommand *ic; CreateFolderData *data; gchar *encoded_fname = NULL; data = camel_imapx_job_get_data (job); - g_return_if_fail (data != NULL); + g_return_val_if_fail (data != NULL, FALSE); encoded_fname = camel_utf8_utf7 (data->folder_name); + ic = camel_imapx_command_new ( is, "CREATE", NULL, "CREATE %s", encoded_fname); ic->pri = job->pri; camel_imapx_command_set_job (ic, job); ic->complete = imapx_command_create_folder_done; - imapx_command_queue (is, ic); g_free (encoded_fname); + + return imapx_command_queue (is, ic, cancellable, error); } /* ********************************************************************** */ @@ -5616,6 +5681,7 @@ imapx_job_create_folder_start (CamelIMAPXJob *job, static gboolean imapx_command_delete_folder_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic, + GCancellable *cancellable, GError **error) { CamelIMAPXJob *job; @@ -5637,39 +5703,46 @@ imapx_command_delete_folder_done (CamelIMAPXServer *is, return success; } -static void +static gboolean imapx_job_delete_folder_start (CamelIMAPXJob *job, - CamelIMAPXServer *is) + CamelIMAPXServer *is, + GCancellable *cancellable, + GError **error) { CamelIMAPXCommand *ic; CamelIMAPXStore *store; DeleteFolderData *data; gchar *encoded_fname = NULL; + gboolean success = FALSE; data = camel_imapx_job_get_data (job); - g_return_if_fail (data != NULL); + g_return_val_if_fail (data != NULL, FALSE); store = camel_imapx_server_ref_store (is); encoded_fname = imapx_encode_folder_name (store, data->folder_name); job->folder = camel_store_get_folder_sync ( - CAMEL_STORE (store), "INBOX", 0, - job->cancellable, &job->error); + CAMEL_STORE (store), "INBOX", 0, cancellable, error); - /* Make sure the to-be-deleted folder is not - * selected by selecting INBOX for this operation. */ - ic = camel_imapx_command_new ( - is, "DELETE", job->folder, - "DELETE %s", encoded_fname); - ic->pri = job->pri; - camel_imapx_command_set_job (ic, job); - ic->complete = imapx_command_delete_folder_done; - imapx_command_queue (is, ic); + if (job->folder != NULL) { + /* Make sure the to-be-deleted folder is not + * selected by selecting INBOX for this operation. */ + ic = camel_imapx_command_new ( + is, "DELETE", job->folder, + "DELETE %s", encoded_fname); + ic->pri = job->pri; + camel_imapx_command_set_job (ic, job); + ic->complete = imapx_command_delete_folder_done; + + success = imapx_command_queue (is, ic, cancellable, error); + } g_free (encoded_fname); g_object_unref (store); + + return success; } /* ********************************************************************** */ @@ -5677,6 +5750,7 @@ imapx_job_delete_folder_start (CamelIMAPXJob *job, static gboolean imapx_command_rename_folder_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic, + GCancellable *cancellable, GError **error) { CamelIMAPXJob *job; @@ -5698,39 +5772,46 @@ imapx_command_rename_folder_done (CamelIMAPXServer *is, return success; } -static void +static gboolean imapx_job_rename_folder_start (CamelIMAPXJob *job, - CamelIMAPXServer *is) + CamelIMAPXServer *is, + GCancellable *cancellable, + GError **error) { CamelIMAPXCommand *ic; CamelIMAPXStore *store; RenameFolderData *data; gchar *en_ofname = NULL, *en_nfname = NULL; + gboolean success = FALSE; data = camel_imapx_job_get_data (job); - g_return_if_fail (data != NULL); + g_return_val_if_fail (data != NULL, FALSE); store = camel_imapx_server_ref_store (is); - job->folder = camel_store_get_folder_sync ( - CAMEL_STORE (store), "INBOX", 0, - job->cancellable, &job->error); - en_ofname = imapx_encode_folder_name (store, data->old_folder_name); en_nfname = imapx_encode_folder_name (store, data->new_folder_name); - ic = camel_imapx_command_new ( - is, "RENAME", job->folder, - "RENAME %s %s", en_ofname, en_nfname); - ic->pri = job->pri; - camel_imapx_command_set_job (ic, job); - ic->complete = imapx_command_rename_folder_done; - imapx_command_queue (is, ic); + job->folder = camel_store_get_folder_sync ( + CAMEL_STORE (store), "INBOX", 0, cancellable, error); + + if (job->folder != NULL) { + ic = camel_imapx_command_new ( + is, "RENAME", job->folder, + "RENAME %s %s", en_ofname, en_nfname); + ic->pri = job->pri; + camel_imapx_command_set_job (ic, job); + ic->complete = imapx_command_rename_folder_done; + + success = imapx_command_queue (is, ic, cancellable, error); + } g_free (en_ofname); g_free (en_nfname); g_object_unref (store); + + return success; } /* ********************************************************************** */ @@ -5738,6 +5819,7 @@ imapx_job_rename_folder_start (CamelIMAPXJob *job, static gboolean imapx_command_noop_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic, + GCancellable *cancellable, GError **error) { CamelIMAPXJob *job; @@ -5759,9 +5841,11 @@ imapx_command_noop_done (CamelIMAPXServer *is, return success; } -static void +static gboolean imapx_job_noop_start (CamelIMAPXJob *job, - CamelIMAPXServer *is) + CamelIMAPXServer *is, + GCancellable *cancellable, + GError **error) { CamelIMAPXCommand *ic; @@ -5774,7 +5858,8 @@ imapx_job_noop_start (CamelIMAPXJob *job, ic->pri = IMAPX_PRIORITY_REFRESH_INFO; else ic->pri = IMAPX_PRIORITY_NOOP; - imapx_command_queue (is, ic); + + return imapx_command_queue (is, ic, cancellable, error); } /* ********************************************************************** */ @@ -5807,6 +5892,7 @@ static struct { static gboolean imapx_command_sync_changes_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic, + GCancellable *cancellable, GError **error) { CamelIMAPXJob *job; @@ -5891,7 +5977,7 @@ imapx_command_sync_changes_done (CamelIMAPXServer *is, } } - camel_folder_summary_save_to_db (job->folder->summary, &job->error); + camel_folder_summary_save_to_db (job->folder->summary, error); camel_store_summary_save ((CamelStoreSummary *)((CamelIMAPXStore *) parent_store)->summary); imapx_unregister_job (is, job); @@ -5902,9 +5988,11 @@ imapx_command_sync_changes_done (CamelIMAPXServer *is, return success; } -static void +static gboolean imapx_job_sync_changes_start (CamelIMAPXJob *job, - CamelIMAPXServer *is) + CamelIMAPXServer *is, + GCancellable *cancellable, + GError **error) { SyncChangesData *data; guint32 i, j; @@ -5913,7 +6001,7 @@ imapx_job_sync_changes_start (CamelIMAPXJob *job, gint on; data = camel_imapx_job_get_data (job); - g_return_if_fail (data != NULL); + g_return_val_if_fail (data != NULL, FALSE); uids = data->changed_uids; @@ -5959,7 +6047,10 @@ imapx_job_sync_changes_start (CamelIMAPXJob *job, if (send == 1 || (i == uids->len - 1 && imapx_uidset_done (&ss, ic))) { job->commands++; camel_imapx_command_add (ic, " %tFLAGS.SILENT (%t)", on?"+":"-", flags_table[j].name); - imapx_command_queue (is, ic); + if (!imapx_command_queue (is, ic, cancellable, error)) { + camel_message_info_free (info); + goto exit; + } ic = NULL; } if (flag == CAMEL_MESSAGE_SEEN) { @@ -5997,7 +6088,8 @@ imapx_job_sync_changes_start (CamelIMAPXJob *job, || (i == c->infos->len - 1 && imapx_uidset_done (&ss, ic))) { job->commands++; camel_imapx_command_add (ic, " %tFLAGS.SILENT (%t)", on?"+":"-", c->name); - imapx_command_queue (is, ic); + if (!imapx_command_queue (is, ic, cancellable, error)) + goto exit; ic = NULL; } } @@ -6005,12 +6097,15 @@ imapx_job_sync_changes_start (CamelIMAPXJob *job, } } +exit: /* Since this may start in another thread ... we need to * lock the commands count, ho hum */ if (job->commands == 0) { imapx_unregister_job (is, job); } + + return TRUE; } static gboolean @@ -6058,13 +6153,12 @@ cancel_all_jobs (CamelIMAPXServer *is, if (!CAMEL_IS_IMAPX_JOB (job)) continue; - if (job->error == NULL) - job->error = g_error_copy (error); + camel_imapx_job_cancel (job); - /* Send a NULL GError since we've already set - * the job's GError, and we're not interested - * in individual command errors. */ - ic->complete (is, ic, NULL); + /* Send a NULL GError since we already cancelled + * the job and we're not interested in individual + * command errors. */ + ic->complete (is, ic, NULL, NULL); } camel_imapx_command_queue_free (queue); diff --git a/docs/reference/camel/camel-sections.txt b/docs/reference/camel/camel-sections.txt index ac64056..bdd9a73 100644 --- a/docs/reference/camel/camel-sections.txt +++ b/docs/reference/camel/camel-sections.txt @@ -817,6 +817,7 @@ camel_imapx_job_new camel_imapx_job_ref camel_imapx_job_unref camel_imapx_job_check +camel_imapx_job_cancel camel_imapx_job_wait camel_imapx_job_done camel_imapx_job_run