|
|
59ad60 |
diff -up evolution-data-server-3.8.5/camel/camel-imapx-conn-manager.c.imapx-conn-manager-ext evolution-data-server-3.8.5/camel/camel-imapx-conn-manager.c
|
|
|
59ad60 |
--- evolution-data-server-3.8.5/camel/camel-imapx-conn-manager.c.imapx-conn-manager-ext 2013-07-23 13:57:46.000000000 +0200
|
|
|
59ad60 |
+++ evolution-data-server-3.8.5/camel/camel-imapx-conn-manager.c 2014-05-13 14:17:43.115983665 +0200
|
|
|
59ad60 |
@@ -47,6 +47,7 @@ struct _CamelIMAPXConnManagerPrivate {
|
|
|
59ad60 |
GList *connections;
|
|
|
59ad60 |
GWeakRef store;
|
|
|
59ad60 |
GRWLock rw_lock;
|
|
|
59ad60 |
+ guint limit_max_connections;
|
|
|
59ad60 |
};
|
|
|
59ad60 |
|
|
|
59ad60 |
struct _ConnectionInfo {
|
|
|
59ad60 |
@@ -54,6 +55,7 @@ struct _ConnectionInfo {
|
|
|
59ad60 |
CamelIMAPXServer *is;
|
|
|
59ad60 |
GHashTable *folder_names;
|
|
|
59ad60 |
gchar *selected_folder;
|
|
|
59ad60 |
+ GError *shutdown_error;
|
|
|
59ad60 |
volatile gint ref_count;
|
|
|
59ad60 |
};
|
|
|
59ad60 |
|
|
|
59ad60 |
@@ -68,7 +70,9 @@ G_DEFINE_TYPE (
|
|
|
59ad60 |
CAMEL_TYPE_OBJECT)
|
|
|
59ad60 |
|
|
|
59ad60 |
static void
|
|
|
59ad60 |
-imapx_conn_shutdown (CamelIMAPXServer *is, CamelIMAPXConnManager *con_man);
|
|
|
59ad60 |
+imapx_conn_shutdown (CamelIMAPXServer *is,
|
|
|
59ad60 |
+ const GError *error,
|
|
|
59ad60 |
+ CamelIMAPXConnManager *con_man);
|
|
|
59ad60 |
|
|
|
59ad60 |
static void
|
|
|
59ad60 |
imapx_conn_update_select (CamelIMAPXServer *is,
|
|
|
59ad60 |
@@ -91,6 +95,7 @@ connection_info_new (CamelIMAPXServer *i
|
|
|
59ad60 |
g_mutex_init (&cinfo->lock);
|
|
|
59ad60 |
cinfo->is = g_object_ref (is);
|
|
|
59ad60 |
cinfo->folder_names = folder_names;
|
|
|
59ad60 |
+ cinfo->shutdown_error = NULL;
|
|
|
59ad60 |
cinfo->ref_count = 1;
|
|
|
59ad60 |
|
|
|
59ad60 |
return cinfo;
|
|
|
59ad60 |
@@ -114,11 +119,15 @@ connection_info_unref (ConnectionInfo *c
|
|
|
59ad60 |
g_return_if_fail (cinfo->ref_count > 0);
|
|
|
59ad60 |
|
|
|
59ad60 |
if (g_atomic_int_dec_and_test (&cinfo->ref_count)) {
|
|
|
59ad60 |
- camel_imapx_server_connect (cinfo->is, NULL, NULL);
|
|
|
59ad60 |
+ camel_imapx_server_shutdown (cinfo->is, cinfo->shutdown_error);
|
|
|
59ad60 |
+ g_signal_handlers_disconnect_matched (cinfo->is, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, imapx_conn_shutdown, NULL);
|
|
|
59ad60 |
+ g_signal_handlers_disconnect_matched (cinfo->is, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, imapx_conn_update_select, NULL);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
g_mutex_clear (&cinfo->lock);
|
|
|
59ad60 |
g_object_unref (cinfo->is);
|
|
|
59ad60 |
g_hash_table_destroy (cinfo->folder_names);
|
|
|
59ad60 |
g_free (cinfo->selected_folder);
|
|
|
59ad60 |
+ g_clear_error (&cinfo->shutdown_error);
|
|
|
59ad60 |
|
|
|
59ad60 |
g_slice_free (ConnectionInfo, cinfo);
|
|
|
59ad60 |
}
|
|
|
59ad60 |
@@ -132,6 +141,7 @@ connection_info_cancel_and_unref (Connec
|
|
|
59ad60 |
|
|
|
59ad60 |
g_signal_handlers_disconnect_matched (cinfo->is, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, imapx_conn_shutdown, NULL);
|
|
|
59ad60 |
g_signal_handlers_disconnect_matched (cinfo->is, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, imapx_conn_update_select, NULL);
|
|
|
59ad60 |
+ camel_imapx_server_shutdown (cinfo->is, cinfo->shutdown_error);
|
|
|
59ad60 |
g_cancellable_cancel (cinfo->is->cancellable);
|
|
|
59ad60 |
connection_info_unref (cinfo);
|
|
|
59ad60 |
}
|
|
|
59ad60 |
@@ -145,8 +155,9 @@ connection_info_is_available (Connection
|
|
|
59ad60 |
|
|
|
59ad60 |
g_mutex_lock (&cinfo->lock);
|
|
|
59ad60 |
|
|
|
59ad60 |
- /* Available means it's not tracking any folder names. */
|
|
|
59ad60 |
- available = (g_hash_table_size (cinfo->folder_names) == 0);
|
|
|
59ad60 |
+ /* Available means it's not tracking any folder names or no jobs are running. */
|
|
|
59ad60 |
+ available = (g_hash_table_size (cinfo->folder_names) == 0) ||
|
|
|
59ad60 |
+ camel_imapx_server_get_command_count (cinfo->is) == 0;
|
|
|
59ad60 |
|
|
|
59ad60 |
g_mutex_unlock (&cinfo->lock);
|
|
|
59ad60 |
|
|
|
59ad60 |
@@ -234,6 +245,23 @@ connection_info_set_selected_folder (Con
|
|
|
59ad60 |
g_mutex_unlock (&cinfo->lock);
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
+static void
|
|
|
59ad60 |
+connection_info_set_shutdown_error (ConnectionInfo *cinfo,
|
|
|
59ad60 |
+ const GError *shutdown_error)
|
|
|
59ad60 |
+{
|
|
|
59ad60 |
+ g_return_if_fail (cinfo != NULL);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_mutex_lock (&cinfo->lock);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (cinfo->shutdown_error != shutdown_error) {
|
|
|
59ad60 |
+ g_clear_error (&cinfo->shutdown_error);
|
|
|
59ad60 |
+ if (shutdown_error)
|
|
|
59ad60 |
+ cinfo->shutdown_error = g_error_copy (shutdown_error);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_mutex_unlock (&cinfo->lock);
|
|
|
59ad60 |
+}
|
|
|
59ad60 |
+
|
|
|
59ad60 |
static GList *
|
|
|
59ad60 |
imapx_conn_manager_list_info (CamelIMAPXConnManager *con_man)
|
|
|
59ad60 |
{
|
|
|
59ad60 |
@@ -416,11 +444,9 @@ camel_imapx_conn_manager_init (CamelIMAP
|
|
|
59ad60 |
g_rw_lock_init (&con_man->priv->rw_lock);
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
-/* Static functions go here */
|
|
|
59ad60 |
-
|
|
|
59ad60 |
-/* TODO destroy unused connections in a time-out loop */
|
|
|
59ad60 |
static void
|
|
|
59ad60 |
imapx_conn_shutdown (CamelIMAPXServer *is,
|
|
|
59ad60 |
+ const GError *error,
|
|
|
59ad60 |
CamelIMAPXConnManager *con_man)
|
|
|
59ad60 |
{
|
|
|
59ad60 |
ConnectionInfo *cinfo;
|
|
|
59ad60 |
@@ -432,6 +458,14 @@ imapx_conn_shutdown (CamelIMAPXServer *i
|
|
|
59ad60 |
imapx_conn_manager_remove_info (con_man, cinfo);
|
|
|
59ad60 |
connection_info_unref (cinfo);
|
|
|
59ad60 |
}
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ /* If one connection ends with this error, then it means all
|
|
|
59ad60 |
+ other opened connections also may end with the same error,
|
|
|
59ad60 |
+ thus better to kill them all from the list of connections.
|
|
|
59ad60 |
+ */
|
|
|
59ad60 |
+ if (g_error_matches (error, CAMEL_IMAPX_SERVER_ERROR, CAMEL_IMAPX_SERVER_ERROR_TRY_RECONNECT)) {
|
|
|
59ad60 |
+ camel_imapx_conn_manager_close_connections (con_man, error);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
static void
|
|
|
59ad60 |
@@ -451,14 +485,10 @@ imapx_conn_update_select (CamelIMAPXServ
|
|
|
59ad60 |
old_selected_folder = connection_info_dup_selected_folder (cinfo);
|
|
|
59ad60 |
|
|
|
59ad60 |
if (old_selected_folder != NULL) {
|
|
|
59ad60 |
- IMAPXJobQueueInfo *jinfo;
|
|
|
59ad60 |
-
|
|
|
59ad60 |
- jinfo = camel_imapx_server_get_job_queue_info (is);
|
|
|
59ad60 |
- if (!g_hash_table_lookup (jinfo->folders, old_selected_folder)) {
|
|
|
59ad60 |
+ if (!camel_imapx_server_folder_name_in_jobs (is, old_selected_folder)) {
|
|
|
59ad60 |
connection_info_remove_folder_name (cinfo, old_selected_folder);
|
|
|
59ad60 |
c (is->tagprefix, "Removed folder %s from connection folder list - select changed \n", old_selected_folder);
|
|
|
59ad60 |
}
|
|
|
59ad60 |
- camel_imapx_destroy_job_queue_info (jinfo);
|
|
|
59ad60 |
|
|
|
59ad60 |
g_free (old_selected_folder);
|
|
|
59ad60 |
}
|
|
|
59ad60 |
@@ -471,14 +501,15 @@ imapx_conn_update_select (CamelIMAPXServ
|
|
|
59ad60 |
/* This should find a connection if the slots are full, returns NULL if there are slots available for a new connection for a folder */
|
|
|
59ad60 |
static CamelIMAPXServer *
|
|
|
59ad60 |
imapx_find_connection_unlocked (CamelIMAPXConnManager *con_man,
|
|
|
59ad60 |
- const gchar *folder_name)
|
|
|
59ad60 |
+ const gchar *folder_name,
|
|
|
59ad60 |
+ gboolean for_expensive_job)
|
|
|
59ad60 |
{
|
|
|
59ad60 |
CamelStore *store;
|
|
|
59ad60 |
CamelSettings *settings;
|
|
|
59ad60 |
CamelIMAPXServer *is = NULL;
|
|
|
59ad60 |
ConnectionInfo *cinfo = NULL;
|
|
|
59ad60 |
GList *list, *link;
|
|
|
59ad60 |
- guint concurrent_connections;
|
|
|
59ad60 |
+ guint concurrent_connections, opened_connections, expensive_connections = 0;
|
|
|
59ad60 |
guint min_jobs = G_MAXUINT;
|
|
|
59ad60 |
|
|
|
59ad60 |
/* Caller must be holding CON_WRITE_LOCK. */
|
|
|
59ad60 |
@@ -492,24 +523,85 @@ imapx_find_connection_unlocked (CamelIMA
|
|
|
59ad60 |
camel_imapx_settings_get_concurrent_connections (
|
|
|
59ad60 |
CAMEL_IMAPX_SETTINGS (settings));
|
|
|
59ad60 |
|
|
|
59ad60 |
+ if (con_man->priv->limit_max_connections > 0 &&
|
|
|
59ad60 |
+ con_man->priv->limit_max_connections < concurrent_connections)
|
|
|
59ad60 |
+ concurrent_connections = con_man->priv->limit_max_connections;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
g_object_unref (settings);
|
|
|
59ad60 |
|
|
|
59ad60 |
/* XXX Have a dedicated connection for INBOX ? */
|
|
|
59ad60 |
|
|
|
59ad60 |
+ opened_connections = g_list_length (con_man->priv->connections);
|
|
|
59ad60 |
list = con_man->priv->connections;
|
|
|
59ad60 |
|
|
|
59ad60 |
/* If a folder was not given, find the least-busy connection. */
|
|
|
59ad60 |
- if (folder_name == NULL)
|
|
|
59ad60 |
+ if (folder_name == NULL) {
|
|
|
59ad60 |
goto least_busy;
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
|
|
|
59ad60 |
/* First try to find a connection already handling this folder. */
|
|
|
59ad60 |
for (link = list; link != NULL; link = g_list_next (link)) {
|
|
|
59ad60 |
ConnectionInfo *candidate = link->data;
|
|
|
59ad60 |
|
|
|
59ad60 |
- if (connection_info_has_folder_name (candidate, folder_name)) {
|
|
|
59ad60 |
+ if (camel_imapx_server_has_expensive_command (candidate->is))
|
|
|
59ad60 |
+ expensive_connections++;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (connection_info_has_folder_name (candidate, folder_name) &&
|
|
|
59ad60 |
+ (opened_connections >= concurrent_connections || for_expensive_job || !camel_imapx_server_has_expensive_command (candidate->is))) {
|
|
|
59ad60 |
+ if (cinfo) {
|
|
|
59ad60 |
+ /* group expensive jobs into one connection */
|
|
|
59ad60 |
+ if (for_expensive_job && camel_imapx_server_has_expensive_command (cinfo->is))
|
|
|
59ad60 |
+ continue;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (!for_expensive_job && camel_imapx_server_get_command_count (cinfo->is) < camel_imapx_server_get_command_count (candidate->is))
|
|
|
59ad60 |
+ continue;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ connection_info_unref (cinfo);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
cinfo = connection_info_ref (candidate);
|
|
|
59ad60 |
+ if (for_expensive_job && camel_imapx_server_has_expensive_command (cinfo->is))
|
|
|
59ad60 |
+ goto exit;
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ least_busy:
|
|
|
59ad60 |
+ if (for_expensive_job) {
|
|
|
59ad60 |
+ /* allow only half connections being with expensive operations */
|
|
|
59ad60 |
+ if (expensive_connections > 0 &&
|
|
|
59ad60 |
+ expensive_connections < concurrent_connections / 2 &&
|
|
|
59ad60 |
+ opened_connections < concurrent_connections)
|
|
|
59ad60 |
goto exit;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ /* cinfo here doesn't have any expensive command, thus ignore it */
|
|
|
59ad60 |
+ if (cinfo) {
|
|
|
59ad60 |
+ connection_info_unref (cinfo);
|
|
|
59ad60 |
+ cinfo = NULL;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ /* Pick the connection with the least number of jobs in progress among those with expensive jobs. */
|
|
|
59ad60 |
+ for (link = list; link != NULL; link = g_list_next (link)) {
|
|
|
59ad60 |
+ ConnectionInfo *candidate = link->data;
|
|
|
59ad60 |
+ guint jobs;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (!camel_imapx_server_has_expensive_command (candidate->is))
|
|
|
59ad60 |
+ continue;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ jobs = camel_imapx_server_get_command_count (candidate->is);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (cinfo == NULL) {
|
|
|
59ad60 |
+ cinfo = connection_info_ref (candidate);
|
|
|
59ad60 |
+ min_jobs = jobs;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ } else if (jobs < min_jobs) {
|
|
|
59ad60 |
+ connection_info_unref (cinfo);
|
|
|
59ad60 |
+ cinfo = connection_info_ref (candidate);
|
|
|
59ad60 |
+ min_jobs = jobs;
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (cinfo)
|
|
|
59ad60 |
+ goto exit;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
/* Next try to find a connection not handling any folders. */
|
|
|
59ad60 |
@@ -517,44 +609,59 @@ imapx_find_connection_unlocked (CamelIMA
|
|
|
59ad60 |
ConnectionInfo *candidate = link->data;
|
|
|
59ad60 |
|
|
|
59ad60 |
if (connection_info_is_available (candidate)) {
|
|
|
59ad60 |
+ if (cinfo)
|
|
|
59ad60 |
+ connection_info_unref (cinfo);
|
|
|
59ad60 |
cinfo = connection_info_ref (candidate);
|
|
|
59ad60 |
goto exit;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
-least_busy:
|
|
|
59ad60 |
+ /* open a new connection, if there is a room for it */
|
|
|
59ad60 |
+ if (opened_connections < concurrent_connections && (!for_expensive_job || opened_connections < concurrent_connections / 2)) {
|
|
|
59ad60 |
+ if (cinfo && camel_imapx_server_get_command_count (cinfo->is) != 0) {
|
|
|
59ad60 |
+ connection_info_unref (cinfo);
|
|
|
59ad60 |
+ cinfo = NULL;
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+ goto exit;
|
|
|
59ad60 |
+ } else {
|
|
|
59ad60 |
+ if (cinfo)
|
|
|
59ad60 |
+ min_jobs = camel_imapx_server_get_command_count (cinfo->is);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
/* Pick the connection with the least number of jobs in progress. */
|
|
|
59ad60 |
for (link = list; link != NULL; link = g_list_next (link)) {
|
|
|
59ad60 |
ConnectionInfo *candidate = link->data;
|
|
|
59ad60 |
- IMAPXJobQueueInfo *jinfo = NULL;
|
|
|
59ad60 |
-
|
|
|
59ad60 |
- jinfo = camel_imapx_server_get_job_queue_info (candidate->is);
|
|
|
59ad60 |
+ gint n_commands = camel_imapx_server_get_command_count (candidate->is);
|
|
|
59ad60 |
|
|
|
59ad60 |
if (cinfo == NULL) {
|
|
|
59ad60 |
cinfo = connection_info_ref (candidate);
|
|
|
59ad60 |
- min_jobs = jinfo->queue_len;
|
|
|
59ad60 |
+ min_jobs = n_commands;
|
|
|
59ad60 |
|
|
|
59ad60 |
- } else if (jinfo->queue_len < min_jobs) {
|
|
|
59ad60 |
+ } else if (n_commands < min_jobs) {
|
|
|
59ad60 |
connection_info_unref (cinfo);
|
|
|
59ad60 |
cinfo = connection_info_ref (candidate);
|
|
|
59ad60 |
- min_jobs = jinfo->queue_len;
|
|
|
59ad60 |
+ min_jobs = n_commands;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
-
|
|
|
59ad60 |
- camel_imapx_destroy_job_queue_info (jinfo);
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
exit:
|
|
|
59ad60 |
if (cinfo != NULL && folder_name != NULL)
|
|
|
59ad60 |
connection_info_insert_folder_name (cinfo, folder_name);
|
|
|
59ad60 |
|
|
|
59ad60 |
+ if (camel_debug_flag (conman)) {
|
|
|
59ad60 |
+ printf ("%s: for-expensive:%d will return:%p cmd-count:%d has-expensive:%d found:%d; connections opened:%d max:%d\n", G_STRFUNC, for_expensive_job, cinfo, cinfo ? camel_imapx_server_get_command_count (cinfo->is) : -2, cinfo ? camel_imapx_server_has_expensive_command (cinfo->is) : -2, expensive_connections, g_list_length (list), concurrent_connections);
|
|
|
59ad60 |
+ for (link = list; link != NULL; link = g_list_next (link)) {
|
|
|
59ad60 |
+ ConnectionInfo *candidate = link->data;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ printf (" cmds:%d has-expensive:%d avail:%d cinfo:%p server:%p\n", camel_imapx_server_get_command_count (candidate->is), camel_imapx_server_has_expensive_command (candidate->is), connection_info_is_available (candidate), candidate, candidate->is);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
if (cinfo != NULL) {
|
|
|
59ad60 |
is = g_object_ref (cinfo->is);
|
|
|
59ad60 |
connection_info_unref (cinfo);
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
- if (camel_debug_flag (conman))
|
|
|
59ad60 |
- g_assert (!(concurrent_connections == g_list_length (con_man->priv->connections) && is == NULL));
|
|
|
59ad60 |
-
|
|
|
59ad60 |
g_object_unref (store);
|
|
|
59ad60 |
|
|
|
59ad60 |
return is;
|
|
|
59ad60 |
@@ -601,9 +708,11 @@ imapx_create_new_connection_unlocked (Ca
|
|
|
59ad60 |
* authenticate at once, so this should be thread-safe.
|
|
|
59ad60 |
*/
|
|
|
59ad60 |
imapx_store->authenticating_server = g_object_ref (is);
|
|
|
59ad60 |
+ camel_imapx_store_set_authenticating_concurrent_connection (imapx_store, con_man->priv->connections != NULL);
|
|
|
59ad60 |
success = camel_imapx_server_connect (is, cancellable, error);
|
|
|
59ad60 |
g_object_unref (imapx_store->authenticating_server);
|
|
|
59ad60 |
imapx_store->authenticating_server = NULL;
|
|
|
59ad60 |
+ camel_imapx_store_set_authenticating_concurrent_connection (imapx_store, FALSE);
|
|
|
59ad60 |
|
|
|
59ad60 |
if (!success) {
|
|
|
59ad60 |
g_clear_object (&is);
|
|
|
59ad60 |
@@ -626,7 +735,7 @@ imapx_create_new_connection_unlocked (Ca
|
|
|
59ad60 |
con_man->priv->connections = g_list_prepend (
|
|
|
59ad60 |
con_man->priv->connections, cinfo);
|
|
|
59ad60 |
|
|
|
59ad60 |
- c (is->tagprefix, "Created new connection for %s and total connections %d \n", folder_name, g_list_length (con_man->priv->connections));
|
|
|
59ad60 |
+ c (is->tagprefix, "Created new connection %p (server:%p) for %s; total connections %d\n", cinfo, cinfo->is, folder_name, g_list_length (con_man->priv->connections));
|
|
|
59ad60 |
|
|
|
59ad60 |
exit:
|
|
|
59ad60 |
g_object_unref (store);
|
|
|
59ad60 |
@@ -656,6 +765,7 @@ camel_imapx_conn_manager_ref_store (Came
|
|
|
59ad60 |
CamelIMAPXServer *
|
|
|
59ad60 |
camel_imapx_conn_manager_get_connection (CamelIMAPXConnManager *con_man,
|
|
|
59ad60 |
const gchar *folder_name,
|
|
|
59ad60 |
+ gboolean for_expensive_job,
|
|
|
59ad60 |
GCancellable *cancellable,
|
|
|
59ad60 |
GError **error)
|
|
|
59ad60 |
{
|
|
|
59ad60 |
@@ -669,10 +779,36 @@ camel_imapx_conn_manager_get_connection
|
|
|
59ad60 |
|
|
|
59ad60 |
/* Check if we got cancelled while waiting for the lock. */
|
|
|
59ad60 |
if (!g_cancellable_set_error_if_cancelled (cancellable, error)) {
|
|
|
59ad60 |
- is = imapx_find_connection_unlocked (con_man, folder_name);
|
|
|
59ad60 |
- if (is == NULL)
|
|
|
59ad60 |
- is = imapx_create_new_connection_unlocked (
|
|
|
59ad60 |
- con_man, folder_name, cancellable, error);
|
|
|
59ad60 |
+ is = imapx_find_connection_unlocked (con_man, folder_name, for_expensive_job);
|
|
|
59ad60 |
+ if (is == NULL) {
|
|
|
59ad60 |
+ GError *local_error = NULL;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ is = imapx_create_new_connection_unlocked (con_man, folder_name, cancellable, &local_error);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (!is) {
|
|
|
59ad60 |
+ gboolean limit_connections =
|
|
|
59ad60 |
+ g_error_matches (local_error, CAMEL_IMAPX_SERVER_ERROR,
|
|
|
59ad60 |
+ CAMEL_IMAPX_SERVER_ERROR_CONCURRENT_CONNECT_FAILED) &&
|
|
|
59ad60 |
+ con_man->priv->connections;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ c ('*', "Failed to open a new connection, while having %d opened, with error: %s; will limit connections: %s\n",
|
|
|
59ad60 |
+ g_list_length (con_man->priv->connections),
|
|
|
59ad60 |
+ local_error ? local_error->message : "Unknown error",
|
|
|
59ad60 |
+ limit_connections ? "yes" : "no");
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (limit_connections) {
|
|
|
59ad60 |
+ /* limit to one-less than current connection count - be nice to the server */
|
|
|
59ad60 |
+ con_man->priv->limit_max_connections = g_list_length (con_man->priv->connections) - 1;
|
|
|
59ad60 |
+ if (!con_man->priv->limit_max_connections)
|
|
|
59ad60 |
+ con_man->priv->limit_max_connections = 1;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_clear_error (&local_error);
|
|
|
59ad60 |
+ is = imapx_find_connection_unlocked (con_man, folder_name, for_expensive_job);
|
|
|
59ad60 |
+ } else if (local_error) {
|
|
|
59ad60 |
+ g_propagate_error (error, local_error);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
CON_WRITE_UNLOCK (con_man);
|
|
|
59ad60 |
@@ -706,7 +842,6 @@ camel_imapx_conn_manager_update_con_info
|
|
|
59ad60 |
const gchar *folder_name)
|
|
|
59ad60 |
{
|
|
|
59ad60 |
ConnectionInfo *cinfo;
|
|
|
59ad60 |
- IMAPXJobQueueInfo *jinfo;
|
|
|
59ad60 |
|
|
|
59ad60 |
g_return_if_fail (CAMEL_IS_IMAPX_CONN_MANAGER (con_man));
|
|
|
59ad60 |
|
|
|
59ad60 |
@@ -716,28 +851,35 @@ camel_imapx_conn_manager_update_con_info
|
|
|
59ad60 |
if (cinfo == NULL)
|
|
|
59ad60 |
return;
|
|
|
59ad60 |
|
|
|
59ad60 |
- jinfo = camel_imapx_server_get_job_queue_info (cinfo->is);
|
|
|
59ad60 |
- if (!g_hash_table_lookup (jinfo->folders, folder_name)) {
|
|
|
59ad60 |
+ if (camel_imapx_server_folder_name_in_jobs (is, folder_name)) {
|
|
|
59ad60 |
connection_info_remove_folder_name (cinfo, folder_name);
|
|
|
59ad60 |
c (is->tagprefix, "Removed folder %s from connection folder list - op done \n", folder_name);
|
|
|
59ad60 |
}
|
|
|
59ad60 |
- camel_imapx_destroy_job_queue_info (jinfo);
|
|
|
59ad60 |
|
|
|
59ad60 |
connection_info_unref (cinfo);
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
void
|
|
|
59ad60 |
-camel_imapx_conn_manager_close_connections (CamelIMAPXConnManager *con_man)
|
|
|
59ad60 |
+camel_imapx_conn_manager_close_connections (CamelIMAPXConnManager *con_man,
|
|
|
59ad60 |
+ const GError *error)
|
|
|
59ad60 |
{
|
|
|
59ad60 |
+ GList *iter, *connections;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
g_return_if_fail (CAMEL_IS_IMAPX_CONN_MANAGER (con_man));
|
|
|
59ad60 |
|
|
|
59ad60 |
CON_WRITE_LOCK (con_man);
|
|
|
59ad60 |
|
|
|
59ad60 |
- g_list_free_full (
|
|
|
59ad60 |
- con_man->priv->connections,
|
|
|
59ad60 |
- (GDestroyNotify) connection_info_cancel_and_unref);
|
|
|
59ad60 |
+ c('*', "Closing all %d connections, with propagated error: %s\n", g_list_length (con_man->priv->connections), error ? error->message : "none");
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ connections = con_man->priv->connections;
|
|
|
59ad60 |
con_man->priv->connections = NULL;
|
|
|
59ad60 |
|
|
|
59ad60 |
CON_WRITE_UNLOCK (con_man);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ for (iter = connections; iter; iter = g_list_next (iter)) {
|
|
|
59ad60 |
+ connection_info_set_shutdown_error (iter->data, error);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_list_free_full (connections, (GDestroyNotify) connection_info_cancel_and_unref);
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
diff -up evolution-data-server-3.8.5/camel/camel-imapx-conn-manager.h.imapx-conn-manager-ext evolution-data-server-3.8.5/camel/camel-imapx-conn-manager.h
|
|
|
59ad60 |
--- evolution-data-server-3.8.5/camel/camel-imapx-conn-manager.h.imapx-conn-manager-ext 2013-07-23 13:57:56.000000000 +0200
|
|
|
59ad60 |
+++ evolution-data-server-3.8.5/camel/camel-imapx-conn-manager.h 2014-05-13 14:17:43.116983665 +0200
|
|
|
59ad60 |
@@ -71,10 +71,12 @@ CamelIMAPXServer *
|
|
|
59ad60 |
camel_imapx_conn_manager_get_connection
|
|
|
59ad60 |
(CamelIMAPXConnManager *con_man,
|
|
|
59ad60 |
const gchar *folder_name,
|
|
|
59ad60 |
+ gboolean for_expensive_job,
|
|
|
59ad60 |
GCancellable *cancellable,
|
|
|
59ad60 |
GError **error);
|
|
|
59ad60 |
void camel_imapx_conn_manager_close_connections
|
|
|
59ad60 |
- (CamelIMAPXConnManager *con_man);
|
|
|
59ad60 |
+ (CamelIMAPXConnManager *con_man,
|
|
|
59ad60 |
+ const GError *error);
|
|
|
59ad60 |
GList * camel_imapx_conn_manager_get_connections
|
|
|
59ad60 |
(CamelIMAPXConnManager *con_man);
|
|
|
59ad60 |
void camel_imapx_conn_manager_update_con_info
|
|
|
59ad60 |
diff -up evolution-data-server-3.8.5/camel/camel-imapx-folder.c.imapx-conn-manager-ext evolution-data-server-3.8.5/camel/camel-imapx-folder.c
|
|
|
59ad60 |
--- evolution-data-server-3.8.5/camel/camel-imapx-folder.c.imapx-conn-manager-ext 2013-07-23 14:01:51.000000000 +0200
|
|
|
59ad60 |
+++ evolution-data-server-3.8.5/camel/camel-imapx-folder.c 2014-05-13 14:17:43.116983665 +0200
|
|
|
59ad60 |
@@ -303,47 +303,27 @@ imapx_search_by_uids (CamelFolder *folde
|
|
|
59ad60 |
{
|
|
|
59ad60 |
CamelIMAPXFolder *ifolder;
|
|
|
59ad60 |
CamelIMAPXSearch *isearch;
|
|
|
59ad60 |
- CamelIMAPXServer *server = NULL;
|
|
|
59ad60 |
- CamelStore *parent_store;
|
|
|
59ad60 |
GPtrArray *matches;
|
|
|
59ad60 |
- const gchar *folder_name;
|
|
|
59ad60 |
- gboolean online;
|
|
|
59ad60 |
|
|
|
59ad60 |
if (uids->len == 0)
|
|
|
59ad60 |
return g_ptr_array_new ();
|
|
|
59ad60 |
|
|
|
59ad60 |
ifolder = CAMEL_IMAPX_FOLDER (folder);
|
|
|
59ad60 |
- folder_name = camel_folder_get_full_name (folder);
|
|
|
59ad60 |
- parent_store = camel_folder_get_parent_store (folder);
|
|
|
59ad60 |
-
|
|
|
59ad60 |
- online = camel_offline_store_get_online (
|
|
|
59ad60 |
- CAMEL_OFFLINE_STORE (parent_store));
|
|
|
59ad60 |
-
|
|
|
59ad60 |
- if (online) {
|
|
|
59ad60 |
- /* do not panic when the server cannot be reached for whatever reason,
|
|
|
59ad60 |
- * show offline data at least */
|
|
|
59ad60 |
- server = camel_imapx_store_get_server (
|
|
|
59ad60 |
- CAMEL_IMAPX_STORE (parent_store),
|
|
|
59ad60 |
- folder_name, cancellable, NULL);
|
|
|
59ad60 |
- }
|
|
|
59ad60 |
|
|
|
59ad60 |
g_mutex_lock (&ifolder->search_lock);
|
|
|
59ad60 |
|
|
|
59ad60 |
isearch = CAMEL_IMAPX_SEARCH (ifolder->search);
|
|
|
59ad60 |
- camel_imapx_search_set_server (isearch, server);
|
|
|
59ad60 |
|
|
|
59ad60 |
camel_folder_search_set_folder (ifolder->search, folder);
|
|
|
59ad60 |
+ camel_imapx_search_set_cancellable_and_error (isearch, cancellable, error);
|
|
|
59ad60 |
|
|
|
59ad60 |
matches = camel_folder_search_search (
|
|
|
59ad60 |
ifolder->search, expression, uids, cancellable, error);
|
|
|
59ad60 |
|
|
|
59ad60 |
- camel_imapx_search_set_server (isearch, NULL);
|
|
|
59ad60 |
+ camel_imapx_search_set_cancellable_and_error (isearch, NULL, NULL);
|
|
|
59ad60 |
|
|
|
59ad60 |
g_mutex_unlock (&ifolder->search_lock);
|
|
|
59ad60 |
|
|
|
59ad60 |
- if (server != NULL)
|
|
|
59ad60 |
- g_object_unref (server);
|
|
|
59ad60 |
-
|
|
|
59ad60 |
return matches;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
@@ -355,44 +335,24 @@ imapx_count_by_expression (CamelFolder *
|
|
|
59ad60 |
{
|
|
|
59ad60 |
CamelIMAPXFolder *ifolder;
|
|
|
59ad60 |
CamelIMAPXSearch *isearch;
|
|
|
59ad60 |
- CamelIMAPXServer *server = NULL;
|
|
|
59ad60 |
- CamelStore *parent_store;
|
|
|
59ad60 |
- const gchar *folder_name;
|
|
|
59ad60 |
- gboolean online;
|
|
|
59ad60 |
guint32 matches;
|
|
|
59ad60 |
|
|
|
59ad60 |
ifolder = CAMEL_IMAPX_FOLDER (folder);
|
|
|
59ad60 |
- folder_name = camel_folder_get_full_name (folder);
|
|
|
59ad60 |
- parent_store = camel_folder_get_parent_store (folder);
|
|
|
59ad60 |
-
|
|
|
59ad60 |
- online = camel_offline_store_get_online (
|
|
|
59ad60 |
- CAMEL_OFFLINE_STORE (parent_store));
|
|
|
59ad60 |
-
|
|
|
59ad60 |
- if (online) {
|
|
|
59ad60 |
- /* do not panic when the server cannot be reached for whatever reason,
|
|
|
59ad60 |
- * show offline data at least */
|
|
|
59ad60 |
- server = camel_imapx_store_get_server (
|
|
|
59ad60 |
- CAMEL_IMAPX_STORE (parent_store),
|
|
|
59ad60 |
- folder_name, cancellable, NULL);
|
|
|
59ad60 |
- }
|
|
|
59ad60 |
|
|
|
59ad60 |
g_mutex_lock (&ifolder->search_lock);
|
|
|
59ad60 |
|
|
|
59ad60 |
isearch = CAMEL_IMAPX_SEARCH (ifolder->search);
|
|
|
59ad60 |
- camel_imapx_search_set_server (isearch, server);
|
|
|
59ad60 |
|
|
|
59ad60 |
camel_folder_search_set_folder (ifolder->search, folder);
|
|
|
59ad60 |
+ camel_imapx_search_set_cancellable_and_error (isearch, cancellable, error);
|
|
|
59ad60 |
|
|
|
59ad60 |
matches = camel_folder_search_count (
|
|
|
59ad60 |
ifolder->search, expression, cancellable, error);
|
|
|
59ad60 |
|
|
|
59ad60 |
- camel_imapx_search_set_server (isearch, NULL);
|
|
|
59ad60 |
+ camel_imapx_search_set_cancellable_and_error (isearch, NULL, NULL);
|
|
|
59ad60 |
|
|
|
59ad60 |
g_mutex_unlock (&ifolder->search_lock);
|
|
|
59ad60 |
|
|
|
59ad60 |
- if (server != NULL)
|
|
|
59ad60 |
- g_object_unref (server);
|
|
|
59ad60 |
-
|
|
|
59ad60 |
return matches;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
@@ -404,44 +364,24 @@ imapx_search_by_expression (CamelFolder
|
|
|
59ad60 |
{
|
|
|
59ad60 |
CamelIMAPXFolder *ifolder;
|
|
|
59ad60 |
CamelIMAPXSearch *isearch;
|
|
|
59ad60 |
- CamelIMAPXServer *server = NULL;
|
|
|
59ad60 |
- CamelStore *parent_store;
|
|
|
59ad60 |
GPtrArray *matches;
|
|
|
59ad60 |
- const gchar *folder_name;
|
|
|
59ad60 |
- gboolean online;
|
|
|
59ad60 |
|
|
|
59ad60 |
ifolder = CAMEL_IMAPX_FOLDER (folder);
|
|
|
59ad60 |
- folder_name = camel_folder_get_full_name (folder);
|
|
|
59ad60 |
- parent_store = camel_folder_get_parent_store (folder);
|
|
|
59ad60 |
-
|
|
|
59ad60 |
- online = camel_offline_store_get_online (
|
|
|
59ad60 |
- CAMEL_OFFLINE_STORE (parent_store));
|
|
|
59ad60 |
-
|
|
|
59ad60 |
- if (online) {
|
|
|
59ad60 |
- /* do not panic when the server cannot be reached for whatever reason,
|
|
|
59ad60 |
- * show offline data at least */
|
|
|
59ad60 |
- server = camel_imapx_store_get_server (
|
|
|
59ad60 |
- CAMEL_IMAPX_STORE (parent_store),
|
|
|
59ad60 |
- folder_name, cancellable, NULL);
|
|
|
59ad60 |
- }
|
|
|
59ad60 |
|
|
|
59ad60 |
g_mutex_lock (&ifolder->search_lock);
|
|
|
59ad60 |
|
|
|
59ad60 |
isearch = CAMEL_IMAPX_SEARCH (ifolder->search);
|
|
|
59ad60 |
- camel_imapx_search_set_server (isearch, server);
|
|
|
59ad60 |
|
|
|
59ad60 |
camel_folder_search_set_folder (ifolder->search, folder);
|
|
|
59ad60 |
+ camel_imapx_search_set_cancellable_and_error (isearch, cancellable, error);
|
|
|
59ad60 |
|
|
|
59ad60 |
matches = camel_folder_search_search (
|
|
|
59ad60 |
ifolder->search, expression, NULL, cancellable, error);
|
|
|
59ad60 |
|
|
|
59ad60 |
- camel_imapx_search_set_server (isearch, NULL);
|
|
|
59ad60 |
+ camel_imapx_search_set_cancellable_and_error (isearch, NULL, NULL);
|
|
|
59ad60 |
|
|
|
59ad60 |
g_mutex_unlock (&ifolder->search_lock);
|
|
|
59ad60 |
|
|
|
59ad60 |
- if (server != NULL)
|
|
|
59ad60 |
- g_object_unref (server);
|
|
|
59ad60 |
-
|
|
|
59ad60 |
return matches;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
@@ -466,8 +406,11 @@ imapx_append_message_sync (CamelFolder *
|
|
|
59ad60 |
CamelStore *parent_store;
|
|
|
59ad60 |
CamelIMAPXStore *istore;
|
|
|
59ad60 |
CamelIMAPXServer *server;
|
|
|
59ad60 |
+ const gchar *folder_name;
|
|
|
59ad60 |
+ GError *local_error = NULL;
|
|
|
59ad60 |
gboolean success = FALSE;
|
|
|
59ad60 |
|
|
|
59ad60 |
+ folder_name = camel_folder_get_full_name (folder);
|
|
|
59ad60 |
parent_store = camel_folder_get_parent_store (folder);
|
|
|
59ad60 |
istore = CAMEL_IMAPX_STORE (parent_store);
|
|
|
59ad60 |
|
|
|
59ad60 |
@@ -482,11 +425,27 @@ imapx_append_message_sync (CamelFolder *
|
|
|
59ad60 |
if (appended_uid)
|
|
|
59ad60 |
*appended_uid = NULL;
|
|
|
59ad60 |
|
|
|
59ad60 |
- server = camel_imapx_store_get_server (istore, NULL, cancellable, error);
|
|
|
59ad60 |
+ server = camel_imapx_store_get_server (istore, folder_name, FALSE, cancellable, error);
|
|
|
59ad60 |
if (server) {
|
|
|
59ad60 |
success = camel_imapx_server_append_message (
|
|
|
59ad60 |
- server, folder, message, info, appended_uid, cancellable, error);
|
|
|
59ad60 |
+ server, folder, message, info, appended_uid, cancellable, &local_error);
|
|
|
59ad60 |
+ camel_imapx_store_op_done (istore, server, folder_name);
|
|
|
59ad60 |
g_object_unref (server);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ while (!success && g_error_matches (local_error, CAMEL_IMAPX_SERVER_ERROR, CAMEL_IMAPX_SERVER_ERROR_TRY_RECONNECT)) {
|
|
|
59ad60 |
+ g_clear_error (&local_error);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ server = camel_imapx_store_get_server (istore, folder_name, FALSE, cancellable, &local_error);
|
|
|
59ad60 |
+ if (server) {
|
|
|
59ad60 |
+ success = camel_imapx_server_append_message (
|
|
|
59ad60 |
+ server, folder, message, info, appended_uid, cancellable, &local_error);
|
|
|
59ad60 |
+ camel_imapx_store_op_done (istore, server, folder_name);
|
|
|
59ad60 |
+ g_object_unref (server);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (local_error)
|
|
|
59ad60 |
+ g_propagate_error (error, local_error);
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
return success;
|
|
|
59ad60 |
@@ -501,6 +460,7 @@ imapx_expunge_sync (CamelFolder *folder,
|
|
|
59ad60 |
CamelIMAPXStore *istore;
|
|
|
59ad60 |
CamelIMAPXServer *server;
|
|
|
59ad60 |
const gchar *folder_name;
|
|
|
59ad60 |
+ GError *local_error = NULL;
|
|
|
59ad60 |
gboolean success = FALSE;
|
|
|
59ad60 |
|
|
|
59ad60 |
folder_name = camel_folder_get_full_name (folder);
|
|
|
59ad60 |
@@ -515,13 +475,25 @@ imapx_expunge_sync (CamelFolder *folder,
|
|
|
59ad60 |
return FALSE;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
- server = camel_imapx_store_get_server (
|
|
|
59ad60 |
- istore, folder_name, cancellable, error);
|
|
|
59ad60 |
+ server = camel_imapx_store_get_server (istore, folder_name, FALSE, cancellable, error);
|
|
|
59ad60 |
if (server != NULL) {
|
|
|
59ad60 |
- success = camel_imapx_server_expunge (
|
|
|
59ad60 |
- server, folder, cancellable, error);
|
|
|
59ad60 |
+ success = camel_imapx_server_expunge (server, folder, cancellable, &local_error);
|
|
|
59ad60 |
camel_imapx_store_op_done (istore, server, folder_name);
|
|
|
59ad60 |
g_object_unref (server);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ while (!success && g_error_matches (local_error, CAMEL_IMAPX_SERVER_ERROR, CAMEL_IMAPX_SERVER_ERROR_TRY_RECONNECT)) {
|
|
|
59ad60 |
+ g_clear_error (&local_error);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ server = camel_imapx_store_get_server (istore, folder_name, FALSE, cancellable, &local_error);
|
|
|
59ad60 |
+ if (server != NULL) {
|
|
|
59ad60 |
+ success = camel_imapx_server_expunge (server, folder, cancellable, &local_error);
|
|
|
59ad60 |
+ camel_imapx_store_op_done (istore, server, folder_name);
|
|
|
59ad60 |
+ g_object_unref (server);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (local_error)
|
|
|
59ad60 |
+ g_propagate_error (error, local_error);
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
return success;
|
|
|
59ad60 |
@@ -539,6 +511,7 @@ imapx_fetch_messages_sync (CamelFolder *
|
|
|
59ad60 |
CamelIMAPXStore *istore;
|
|
|
59ad60 |
CamelIMAPXServer *server;
|
|
|
59ad60 |
const gchar *folder_name;
|
|
|
59ad60 |
+ GError *local_error = NULL;
|
|
|
59ad60 |
gboolean success = FALSE;
|
|
|
59ad60 |
|
|
|
59ad60 |
folder_name = camel_folder_get_full_name (folder);
|
|
|
59ad60 |
@@ -557,19 +530,66 @@ imapx_fetch_messages_sync (CamelFolder *
|
|
|
59ad60 |
if (!camel_service_connect_sync (service, cancellable, error))
|
|
|
59ad60 |
return FALSE;
|
|
|
59ad60 |
|
|
|
59ad60 |
- server = camel_imapx_store_get_server (
|
|
|
59ad60 |
- istore, folder_name, cancellable, error);
|
|
|
59ad60 |
+ server = camel_imapx_store_get_server (istore, folder_name, TRUE, cancellable, error);
|
|
|
59ad60 |
if (server != NULL) {
|
|
|
59ad60 |
- success = camel_imapx_server_fetch_messages (
|
|
|
59ad60 |
- server, folder, type, limit, cancellable, error);
|
|
|
59ad60 |
+ success = camel_imapx_server_fetch_messages (server, folder, type, limit, cancellable, &local_error);
|
|
|
59ad60 |
camel_imapx_store_op_done (istore, server, folder_name);
|
|
|
59ad60 |
g_object_unref (server);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ while (!success && g_error_matches (local_error, CAMEL_IMAPX_SERVER_ERROR, CAMEL_IMAPX_SERVER_ERROR_TRY_RECONNECT)) {
|
|
|
59ad60 |
+ g_clear_error (&local_error);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ server = camel_imapx_store_get_server (istore, folder_name, TRUE, cancellable, &local_error);
|
|
|
59ad60 |
+ if (server != NULL) {
|
|
|
59ad60 |
+ success = camel_imapx_server_fetch_messages (server, folder, type, limit, cancellable, &local_error);
|
|
|
59ad60 |
+ camel_imapx_store_op_done (istore, server, folder_name);
|
|
|
59ad60 |
+ g_object_unref (server);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (local_error)
|
|
|
59ad60 |
+ g_propagate_error (error, local_error);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
return success;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
static CamelMimeMessage *
|
|
|
59ad60 |
+imapx_get_message_cached (CamelFolder *folder,
|
|
|
59ad60 |
+ const gchar *message_uid,
|
|
|
59ad60 |
+ GCancellable *cancellable)
|
|
|
59ad60 |
+{
|
|
|
59ad60 |
+ CamelIMAPXFolder *imapx_folder;
|
|
|
59ad60 |
+ CamelMimeMessage *msg = NULL;
|
|
|
59ad60 |
+ CamelStream *stream = NULL;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_return_val_if_fail (CAMEL_IS_IMAPX_FOLDER (folder), NULL);
|
|
|
59ad60 |
+ g_return_val_if_fail (message_uid != NULL, NULL);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ imapx_folder = CAMEL_IMAPX_FOLDER (folder);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ stream = camel_data_cache_get (imapx_folder->cache, "cur", message_uid, NULL);
|
|
|
59ad60 |
+ if (stream != NULL) {
|
|
|
59ad60 |
+ gboolean success;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ msg = camel_mime_message_new ();
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_mutex_lock (&imapx_folder->stream_lock);
|
|
|
59ad60 |
+ success = camel_data_wrapper_construct_from_stream_sync (
|
|
|
59ad60 |
+ CAMEL_DATA_WRAPPER (msg), stream, cancellable, NULL);
|
|
|
59ad60 |
+ if (!success) {
|
|
|
59ad60 |
+ g_object_unref (msg);
|
|
|
59ad60 |
+ msg = NULL;
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+ g_mutex_unlock (&imapx_folder->stream_lock);
|
|
|
59ad60 |
+ g_object_unref (stream);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ return msg;
|
|
|
59ad60 |
+}
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+static CamelMimeMessage *
|
|
|
59ad60 |
imapx_get_message_sync (CamelFolder *folder,
|
|
|
59ad60 |
const gchar *uid,
|
|
|
59ad60 |
GCancellable *cancellable,
|
|
|
59ad60 |
@@ -583,6 +603,7 @@ imapx_get_message_sync (CamelFolder *fol
|
|
|
59ad60 |
CamelIMAPXServer *server;
|
|
|
59ad60 |
const gchar *folder_name;
|
|
|
59ad60 |
const gchar *path = NULL;
|
|
|
59ad60 |
+ GError *local_error = NULL;
|
|
|
59ad60 |
gboolean offline_message = FALSE;
|
|
|
59ad60 |
|
|
|
59ad60 |
folder_name = camel_folder_get_full_name (folder);
|
|
|
59ad60 |
@@ -615,14 +636,27 @@ imapx_get_message_sync (CamelFolder *fol
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
server = camel_imapx_store_get_server (
|
|
|
59ad60 |
- istore, folder_name, cancellable, error);
|
|
|
59ad60 |
+ istore, folder_name, FALSE, cancellable, error);
|
|
|
59ad60 |
if (server == NULL)
|
|
|
59ad60 |
return NULL;
|
|
|
59ad60 |
|
|
|
59ad60 |
- stream = camel_imapx_server_get_message (
|
|
|
59ad60 |
- server, folder, uid, cancellable, error);
|
|
|
59ad60 |
+ stream = camel_imapx_server_get_message (server, folder, uid, cancellable, &local_error);
|
|
|
59ad60 |
camel_imapx_store_op_done (istore, server, folder_name);
|
|
|
59ad60 |
g_object_unref (server);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ while (!stream && g_error_matches (local_error, CAMEL_IMAPX_SERVER_ERROR, CAMEL_IMAPX_SERVER_ERROR_TRY_RECONNECT)) {
|
|
|
59ad60 |
+ g_clear_error (&local_error);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ server = camel_imapx_store_get_server (istore, folder_name, FALSE, cancellable, &local_error);
|
|
|
59ad60 |
+ if (server) {
|
|
|
59ad60 |
+ stream = camel_imapx_server_get_message (server, folder, uid, cancellable, &local_error);
|
|
|
59ad60 |
+ camel_imapx_store_op_done (istore, server, folder_name);
|
|
|
59ad60 |
+ g_object_unref (server);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (local_error)
|
|
|
59ad60 |
+ g_propagate_error (error, local_error);
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
if (stream != NULL) {
|
|
|
59ad60 |
@@ -675,6 +709,7 @@ imapx_get_quota_info_sync (CamelFolder *
|
|
|
59ad60 |
CamelFolderQuotaInfo *quota_info = NULL;
|
|
|
59ad60 |
const gchar *folder_name;
|
|
|
59ad60 |
gchar **quota_root_names;
|
|
|
59ad60 |
+ GError *local_error = NULL;
|
|
|
59ad60 |
gboolean success = FALSE;
|
|
|
59ad60 |
|
|
|
59ad60 |
folder_name = camel_folder_get_full_name (folder);
|
|
|
59ad60 |
@@ -682,14 +717,29 @@ imapx_get_quota_info_sync (CamelFolder *
|
|
|
59ad60 |
|
|
|
59ad60 |
server = camel_imapx_store_get_server (
|
|
|
59ad60 |
CAMEL_IMAPX_STORE (parent_store),
|
|
|
59ad60 |
- folder_name, cancellable, error);
|
|
|
59ad60 |
+ folder_name, FALSE, cancellable, error);
|
|
|
59ad60 |
|
|
|
59ad60 |
if (server != NULL) {
|
|
|
59ad60 |
- success = camel_imapx_server_update_quota_info (
|
|
|
59ad60 |
- server, folder_name, cancellable, error);
|
|
|
59ad60 |
+ success = camel_imapx_server_update_quota_info (server, folder_name, cancellable, &local_error);
|
|
|
59ad60 |
+ camel_imapx_store_op_done (CAMEL_IMAPX_STORE (parent_store), server, folder_name);
|
|
|
59ad60 |
g_object_unref (server);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ while (!success && g_error_matches (local_error, CAMEL_IMAPX_SERVER_ERROR, CAMEL_IMAPX_SERVER_ERROR_TRY_RECONNECT)) {
|
|
|
59ad60 |
+ g_clear_error (&local_error);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ server = camel_imapx_store_get_server (CAMEL_IMAPX_STORE (parent_store), folder_name, FALSE, cancellable, &local_error);
|
|
|
59ad60 |
+ if (server) {
|
|
|
59ad60 |
+ success = camel_imapx_server_update_quota_info (server, folder_name, cancellable, &local_error);
|
|
|
59ad60 |
+ camel_imapx_store_op_done (CAMEL_IMAPX_STORE (parent_store), server, folder_name);
|
|
|
59ad60 |
+ g_object_unref (server);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (local_error)
|
|
|
59ad60 |
+ g_propagate_error (error, local_error);
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
+
|
|
|
59ad60 |
if (!success)
|
|
|
59ad60 |
return NULL;
|
|
|
59ad60 |
|
|
|
59ad60 |
@@ -734,6 +784,7 @@ imapx_refresh_info_sync (CamelFolder *fo
|
|
|
59ad60 |
CamelIMAPXStore *istore;
|
|
|
59ad60 |
CamelIMAPXServer *server;
|
|
|
59ad60 |
const gchar *folder_name;
|
|
|
59ad60 |
+ GError *local_error = NULL;
|
|
|
59ad60 |
gboolean success = FALSE;
|
|
|
59ad60 |
|
|
|
59ad60 |
folder_name = camel_folder_get_full_name (folder);
|
|
|
59ad60 |
@@ -752,13 +803,25 @@ imapx_refresh_info_sync (CamelFolder *fo
|
|
|
59ad60 |
if (!camel_service_connect_sync (service, cancellable, error))
|
|
|
59ad60 |
return FALSE;
|
|
|
59ad60 |
|
|
|
59ad60 |
- server = camel_imapx_store_get_server (
|
|
|
59ad60 |
- istore, folder_name, cancellable, error);
|
|
|
59ad60 |
+ server = camel_imapx_store_get_server (istore, folder_name, TRUE, cancellable, error);
|
|
|
59ad60 |
if (server != NULL) {
|
|
|
59ad60 |
- success = camel_imapx_server_refresh_info (
|
|
|
59ad60 |
- server, folder, cancellable, error);
|
|
|
59ad60 |
+ success = camel_imapx_server_refresh_info (server, folder, cancellable, &local_error);
|
|
|
59ad60 |
camel_imapx_store_op_done (istore, server, folder_name);
|
|
|
59ad60 |
g_object_unref (server);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ while (!success && g_error_matches (local_error, CAMEL_IMAPX_SERVER_ERROR, CAMEL_IMAPX_SERVER_ERROR_TRY_RECONNECT)) {
|
|
|
59ad60 |
+ g_clear_error (&local_error);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ server = camel_imapx_store_get_server (istore, folder_name, TRUE, cancellable, &local_error);
|
|
|
59ad60 |
+ if (server != NULL) {
|
|
|
59ad60 |
+ success = camel_imapx_server_refresh_info (server, folder, cancellable, &local_error);
|
|
|
59ad60 |
+ camel_imapx_store_op_done (istore, server, folder_name);
|
|
|
59ad60 |
+ g_object_unref (server);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (local_error)
|
|
|
59ad60 |
+ g_propagate_error (error, local_error);
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
return success;
|
|
|
59ad60 |
@@ -920,6 +983,7 @@ imapx_synchronize_sync (CamelFolder *fol
|
|
|
59ad60 |
CamelIMAPXStore *istore;
|
|
|
59ad60 |
CamelIMAPXServer *server;
|
|
|
59ad60 |
const gchar *folder_name;
|
|
|
59ad60 |
+ GError *local_error = NULL;
|
|
|
59ad60 |
gboolean success = FALSE;
|
|
|
59ad60 |
|
|
|
59ad60 |
folder_name = camel_folder_get_full_name (folder);
|
|
|
59ad60 |
@@ -934,13 +998,25 @@ imapx_synchronize_sync (CamelFolder *fol
|
|
|
59ad60 |
return FALSE;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
+ /* while it can be expensive job, do not treat it as such, to avoid a blockage
|
|
|
59ad60 |
+ by really expensive jobs */
|
|
|
59ad60 |
server = camel_imapx_store_get_server (
|
|
|
59ad60 |
- istore, folder_name, cancellable, error);
|
|
|
59ad60 |
+ istore, folder_name, FALSE, cancellable, error);
|
|
|
59ad60 |
if (server != NULL) {
|
|
|
59ad60 |
gboolean need_to_expunge;
|
|
|
59ad60 |
|
|
|
59ad60 |
- success = camel_imapx_server_sync_changes (
|
|
|
59ad60 |
- server, folder, cancellable, error);
|
|
|
59ad60 |
+ success = camel_imapx_server_sync_changes (server, folder, cancellable, &local_error);
|
|
|
59ad60 |
+ while (!success && g_error_matches (local_error, CAMEL_IMAPX_SERVER_ERROR, CAMEL_IMAPX_SERVER_ERROR_TRY_RECONNECT)) {
|
|
|
59ad60 |
+ camel_imapx_store_op_done (istore, server, folder_name);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_clear_error (&local_error);
|
|
|
59ad60 |
+ g_clear_object (&server);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ server = camel_imapx_store_get_server (istore, folder_name, FALSE, cancellable, &local_error);
|
|
|
59ad60 |
+ if (server) {
|
|
|
59ad60 |
+ success = camel_imapx_server_sync_changes (server, folder, cancellable, &local_error);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
|
|
|
59ad60 |
if (success) {
|
|
|
59ad60 |
success = imapx_move_to_real_junk (
|
|
|
59ad60 |
@@ -959,12 +1035,29 @@ imapx_synchronize_sync (CamelFolder *fol
|
|
|
59ad60 |
/* Sync twice - make sure deleted flags are written out,
|
|
|
59ad60 |
* then sync again incase expunge changed anything */
|
|
|
59ad60 |
|
|
|
59ad60 |
- if (success && expunge)
|
|
|
59ad60 |
- success = camel_imapx_server_expunge (
|
|
|
59ad60 |
- server, folder, cancellable, error);
|
|
|
59ad60 |
+ if (success && expunge) {
|
|
|
59ad60 |
+ success = camel_imapx_server_expunge (server, folder, cancellable, &local_error);
|
|
|
59ad60 |
|
|
|
59ad60 |
- camel_imapx_store_op_done (istore, server, folder_name);
|
|
|
59ad60 |
- g_object_unref (server);
|
|
|
59ad60 |
+ while (!success && g_error_matches (local_error, CAMEL_IMAPX_SERVER_ERROR, CAMEL_IMAPX_SERVER_ERROR_TRY_RECONNECT)) {
|
|
|
59ad60 |
+ camel_imapx_store_op_done (istore, server, folder_name);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_clear_error (&local_error);
|
|
|
59ad60 |
+ g_clear_object (&server);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ server = camel_imapx_store_get_server (istore, folder_name, FALSE, cancellable, &local_error);
|
|
|
59ad60 |
+ if (server) {
|
|
|
59ad60 |
+ success = camel_imapx_server_expunge (server, folder, cancellable, &local_error);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (local_error)
|
|
|
59ad60 |
+ g_propagate_error (error, local_error);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (server) {
|
|
|
59ad60 |
+ camel_imapx_store_op_done (istore, server, folder_name);
|
|
|
59ad60 |
+ g_object_unref (server);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
return success;
|
|
|
59ad60 |
@@ -980,6 +1073,7 @@ imapx_synchronize_message_sync (CamelFol
|
|
|
59ad60 |
CamelIMAPXStore *istore;
|
|
|
59ad60 |
CamelIMAPXServer *server;
|
|
|
59ad60 |
const gchar *folder_name;
|
|
|
59ad60 |
+ GError *local_error = NULL;
|
|
|
59ad60 |
gboolean success = FALSE;
|
|
|
59ad60 |
|
|
|
59ad60 |
folder_name = camel_folder_get_full_name (folder);
|
|
|
59ad60 |
@@ -995,14 +1089,27 @@ imapx_synchronize_message_sync (CamelFol
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
server = camel_imapx_store_get_server (
|
|
|
59ad60 |
- istore, folder_name, cancellable, error);
|
|
|
59ad60 |
+ istore, folder_name, FALSE, cancellable, error);
|
|
|
59ad60 |
if (server != NULL) {
|
|
|
59ad60 |
- success = camel_imapx_server_sync_message (
|
|
|
59ad60 |
- server, folder, uid, cancellable, error);
|
|
|
59ad60 |
+ success = camel_imapx_server_sync_message (server, folder, uid, cancellable, &local_error);
|
|
|
59ad60 |
camel_imapx_store_op_done (istore, server, folder_name);
|
|
|
59ad60 |
g_object_unref (server);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ while (!success && g_error_matches (local_error, CAMEL_IMAPX_SERVER_ERROR, CAMEL_IMAPX_SERVER_ERROR_TRY_RECONNECT)) {
|
|
|
59ad60 |
+ g_clear_error (&local_error);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ server = camel_imapx_store_get_server (istore, folder_name, FALSE, cancellable, &local_error);
|
|
|
59ad60 |
+ if (server != NULL) {
|
|
|
59ad60 |
+ success = camel_imapx_server_sync_message (server, folder, uid, cancellable, &local_error);
|
|
|
59ad60 |
+ camel_imapx_store_op_done (istore, server, folder_name);
|
|
|
59ad60 |
+ g_object_unref (server);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
+ if (local_error)
|
|
|
59ad60 |
+ g_propagate_error (error, local_error);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
return success;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
@@ -1019,6 +1126,7 @@ imapx_transfer_messages_to_sync (CamelFo
|
|
|
59ad60 |
CamelIMAPXStore *istore;
|
|
|
59ad60 |
CamelIMAPXServer *server;
|
|
|
59ad60 |
const gchar *folder_name;
|
|
|
59ad60 |
+ GError *local_error = NULL;
|
|
|
59ad60 |
gboolean success = FALSE;
|
|
|
59ad60 |
|
|
|
59ad60 |
folder_name = camel_folder_get_full_name (source);
|
|
|
59ad60 |
@@ -1034,15 +1142,31 @@ imapx_transfer_messages_to_sync (CamelFo
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
server = camel_imapx_store_get_server (
|
|
|
59ad60 |
- istore, folder_name, cancellable, error);
|
|
|
59ad60 |
+ istore, folder_name, FALSE, cancellable, error);
|
|
|
59ad60 |
if (server != NULL) {
|
|
|
59ad60 |
success = camel_imapx_server_copy_message (
|
|
|
59ad60 |
server, source, dest, uids,
|
|
|
59ad60 |
- delete_originals, cancellable, error);
|
|
|
59ad60 |
+ delete_originals, cancellable, &local_error);
|
|
|
59ad60 |
camel_imapx_store_op_done (istore, server, folder_name);
|
|
|
59ad60 |
g_object_unref (server);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ while (!success && g_error_matches (local_error, CAMEL_IMAPX_SERVER_ERROR, CAMEL_IMAPX_SERVER_ERROR_TRY_RECONNECT)) {
|
|
|
59ad60 |
+ g_clear_error (&local_error);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ server = camel_imapx_store_get_server (istore, folder_name, FALSE, cancellable, &local_error);
|
|
|
59ad60 |
+ if (server != NULL) {
|
|
|
59ad60 |
+ success = camel_imapx_server_copy_message (
|
|
|
59ad60 |
+ server, source, dest, uids,
|
|
|
59ad60 |
+ delete_originals, cancellable, &local_error);
|
|
|
59ad60 |
+ camel_imapx_store_op_done (istore, server, folder_name);
|
|
|
59ad60 |
+ g_object_unref (server);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
+ if (local_error)
|
|
|
59ad60 |
+ g_propagate_error (error, local_error);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
/* update destination folder only if not frozen, to not update
|
|
|
59ad60 |
* for each single message transfer during filtering
|
|
|
59ad60 |
*/
|
|
|
59ad60 |
@@ -1102,6 +1226,7 @@ camel_imapx_folder_class_init (CamelIMAP
|
|
|
59ad60 |
folder_class->append_message_sync = imapx_append_message_sync;
|
|
|
59ad60 |
folder_class->expunge_sync = imapx_expunge_sync;
|
|
|
59ad60 |
folder_class->fetch_messages_sync = imapx_fetch_messages_sync;
|
|
|
59ad60 |
+ folder_class->get_message_cached = imapx_get_message_cached;
|
|
|
59ad60 |
folder_class->get_message_sync = imapx_get_message_sync;
|
|
|
59ad60 |
folder_class->get_quota_info_sync = imapx_get_quota_info_sync;
|
|
|
59ad60 |
folder_class->purge_message_cache_sync = imapx_purge_message_cache_sync;
|
|
|
59ad60 |
@@ -1238,12 +1363,17 @@ camel_imapx_folder_new (CamelStore *stor
|
|
|
59ad60 |
return NULL;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
+ /* Ensure cache will never expire, otherwise
|
|
|
59ad60 |
+ * it causes redownload of messages. */
|
|
|
59ad60 |
+ camel_data_cache_set_expire_age (ifolder->cache, -1);
|
|
|
59ad60 |
+ camel_data_cache_set_expire_access (ifolder->cache, -1);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
state_file = g_build_filename (folder_dir, "cmeta", NULL);
|
|
|
59ad60 |
camel_object_set_state_filename (CAMEL_OBJECT (folder), state_file);
|
|
|
59ad60 |
g_free (state_file);
|
|
|
59ad60 |
camel_object_state_read (CAMEL_OBJECT (folder));
|
|
|
59ad60 |
|
|
|
59ad60 |
- ifolder->search = camel_imapx_search_new ();
|
|
|
59ad60 |
+ ifolder->search = camel_imapx_search_new (CAMEL_IMAPX_STORE (store));
|
|
|
59ad60 |
g_mutex_init (&ifolder->search_lock);
|
|
|
59ad60 |
g_mutex_init (&ifolder->stream_lock);
|
|
|
59ad60 |
ifolder->ignore_recent = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, NULL);
|
|
|
59ad60 |
diff -up evolution-data-server-3.8.5/camel/camel-imapx-search.c.imapx-conn-manager-ext evolution-data-server-3.8.5/camel/camel-imapx-search.c
|
|
|
59ad60 |
--- evolution-data-server-3.8.5/camel/camel-imapx-search.c.imapx-conn-manager-ext 2014-05-13 14:17:43.103983666 +0200
|
|
|
59ad60 |
+++ evolution-data-server-3.8.5/camel/camel-imapx-search.c 2014-05-13 14:17:43.116983665 +0200
|
|
|
59ad60 |
@@ -16,6 +16,7 @@
|
|
|
59ad60 |
*
|
|
|
59ad60 |
*/
|
|
|
59ad60 |
|
|
|
59ad60 |
+#include "camel-imapx-store.h"
|
|
|
59ad60 |
#include "camel-imapx-search.h"
|
|
|
59ad60 |
|
|
|
59ad60 |
#include "camel-offline-store.h"
|
|
|
59ad60 |
@@ -26,13 +27,16 @@
|
|
|
59ad60 |
((obj), CAMEL_TYPE_IMAPX_SEARCH, CamelIMAPXSearchPrivate))
|
|
|
59ad60 |
|
|
|
59ad60 |
struct _CamelIMAPXSearchPrivate {
|
|
|
59ad60 |
- GWeakRef server;
|
|
|
59ad60 |
+ GWeakRef imapx_store;
|
|
|
59ad60 |
gint *local_data_search; /* not NULL, if testing whether all used headers are all locally available */
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ GCancellable *cancellable; /* not referenced */
|
|
|
59ad60 |
+ GError **error; /* not referenced */
|
|
|
59ad60 |
};
|
|
|
59ad60 |
|
|
|
59ad60 |
enum {
|
|
|
59ad60 |
PROP_0,
|
|
|
59ad60 |
- PROP_SERVER
|
|
|
59ad60 |
+ PROP_STORE
|
|
|
59ad60 |
};
|
|
|
59ad60 |
|
|
|
59ad60 |
G_DEFINE_TYPE (
|
|
|
59ad60 |
@@ -47,8 +51,8 @@ imapx_search_set_property (GObject *obje
|
|
|
59ad60 |
GParamSpec *pspec)
|
|
|
59ad60 |
{
|
|
|
59ad60 |
switch (property_id) {
|
|
|
59ad60 |
- case PROP_SERVER:
|
|
|
59ad60 |
- camel_imapx_search_set_server (
|
|
|
59ad60 |
+ case PROP_STORE:
|
|
|
59ad60 |
+ camel_imapx_search_set_store (
|
|
|
59ad60 |
CAMEL_IMAPX_SEARCH (object),
|
|
|
59ad60 |
g_value_get_object (value));
|
|
|
59ad60 |
return;
|
|
|
59ad60 |
@@ -64,10 +68,10 @@ imapx_search_get_property (GObject *obje
|
|
|
59ad60 |
GParamSpec *pspec)
|
|
|
59ad60 |
{
|
|
|
59ad60 |
switch (property_id) {
|
|
|
59ad60 |
- case PROP_SERVER:
|
|
|
59ad60 |
+ case PROP_STORE:
|
|
|
59ad60 |
g_value_take_object (
|
|
|
59ad60 |
value,
|
|
|
59ad60 |
- camel_imapx_search_ref_server (
|
|
|
59ad60 |
+ camel_imapx_search_ref_store (
|
|
|
59ad60 |
CAMEL_IMAPX_SEARCH (object)));
|
|
|
59ad60 |
return;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
@@ -82,7 +86,7 @@ imapx_search_dispose (GObject *object)
|
|
|
59ad60 |
|
|
|
59ad60 |
priv = CAMEL_IMAPX_SEARCH_GET_PRIVATE (object);
|
|
|
59ad60 |
|
|
|
59ad60 |
- g_weak_ref_set (&priv->server, NULL);
|
|
|
59ad60 |
+ g_weak_ref_set (&priv->imapx_store, NULL);
|
|
|
59ad60 |
|
|
|
59ad60 |
/* Chain up to parent's dispose() method. */
|
|
|
59ad60 |
G_OBJECT_CLASS (camel_imapx_search_parent_class)->dispose (object);
|
|
|
59ad60 |
@@ -136,31 +140,51 @@ imapx_search_result_match_none (CamelSEx
|
|
|
59ad60 |
static CamelSExpResult *
|
|
|
59ad60 |
imapx_search_process_criteria (CamelSExp *sexp,
|
|
|
59ad60 |
CamelFolderSearch *search,
|
|
|
59ad60 |
- CamelIMAPXServer *server,
|
|
|
59ad60 |
+ CamelIMAPXStore *imapx_store,
|
|
|
59ad60 |
const GString *criteria,
|
|
|
59ad60 |
const gchar *from_function)
|
|
|
59ad60 |
{
|
|
|
59ad60 |
CamelSExpResult *result;
|
|
|
59ad60 |
+ CamelIMAPXSearch *imapx_search = CAMEL_IMAPX_SEARCH (search);
|
|
|
59ad60 |
GPtrArray *uids = NULL;
|
|
|
59ad60 |
- GError *error = NULL;
|
|
|
59ad60 |
+ GError *local_error = NULL;
|
|
|
59ad60 |
+ CamelIMAPXServer *imapx_server;
|
|
|
59ad60 |
+ const gchar *folder_name;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ /* there should always be one, held by one of the callers of this function */
|
|
|
59ad60 |
+ g_warn_if_fail (imapx_store != NULL);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ folder_name = camel_folder_get_full_name (search->folder);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ imapx_server = camel_imapx_store_get_server (imapx_store, folder_name, TRUE, imapx_search->priv->cancellable, &local_error);
|
|
|
59ad60 |
+ if (imapx_server) {
|
|
|
59ad60 |
+ uids = camel_imapx_server_uid_search (imapx_server, search->folder, criteria->str, imapx_search->priv->cancellable, &local_error);
|
|
|
59ad60 |
+ camel_imapx_store_op_done (imapx_store, imapx_server, folder_name);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ while (!uids && g_error_matches (local_error, CAMEL_IMAPX_SERVER_ERROR, CAMEL_IMAPX_SERVER_ERROR_TRY_RECONNECT)) {
|
|
|
59ad60 |
+ g_clear_error (&local_error);
|
|
|
59ad60 |
+ g_clear_object (&imapx_server);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ imapx_server = camel_imapx_store_get_server (imapx_store, folder_name, TRUE, imapx_search->priv->cancellable, &local_error);
|
|
|
59ad60 |
+ if (imapx_server) {
|
|
|
59ad60 |
+ uids = camel_imapx_server_uid_search (imapx_server, search->folder, criteria->str, imapx_search->priv->cancellable, &local_error);
|
|
|
59ad60 |
+ camel_imapx_store_op_done (imapx_store, imapx_server, folder_name);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
|
|
|
59ad60 |
- uids = camel_imapx_server_uid_search (
|
|
|
59ad60 |
- server, search->folder, criteria->str, NULL, &error);
|
|
|
59ad60 |
+ g_clear_object (&imapx_server);
|
|
|
59ad60 |
|
|
|
59ad60 |
/* Sanity check. */
|
|
|
59ad60 |
g_return_val_if_fail (
|
|
|
59ad60 |
- ((uids != NULL) && (error == NULL)) ||
|
|
|
59ad60 |
- ((uids == NULL) && (error != NULL)), NULL);
|
|
|
59ad60 |
+ ((uids != NULL) && (local_error == NULL)) ||
|
|
|
59ad60 |
+ ((uids == NULL) && (local_error != NULL)), NULL);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (local_error != NULL) {
|
|
|
59ad60 |
+ g_propagate_error (imapx_search->priv->error, local_error);
|
|
|
59ad60 |
|
|
|
59ad60 |
- /* XXX No allowance for errors in CamelSExp callbacks!
|
|
|
59ad60 |
- * Dump the error to the console and make like we
|
|
|
59ad60 |
- * got an empty result. */
|
|
|
59ad60 |
- if (error != NULL) {
|
|
|
59ad60 |
- g_warning (
|
|
|
59ad60 |
- "%s: (UID SEARCH %s): %s",
|
|
|
59ad60 |
- from_function, criteria->str, error->message);
|
|
|
59ad60 |
+ /* Make like we've got an empty result */
|
|
|
59ad60 |
uids = g_ptr_array_new ();
|
|
|
59ad60 |
- g_error_free (error);
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
if (search->current != NULL) {
|
|
|
59ad60 |
@@ -183,7 +207,7 @@ imapx_search_match_all (CamelSExp *sexp,
|
|
|
59ad60 |
CamelFolderSearch *search)
|
|
|
59ad60 |
{
|
|
|
59ad60 |
CamelIMAPXSearch *imapx_search = CAMEL_IMAPX_SEARCH (search);
|
|
|
59ad60 |
- CamelIMAPXServer *server;
|
|
|
59ad60 |
+ CamelIMAPXStore *imapx_store;
|
|
|
59ad60 |
CamelSExpResult *result;
|
|
|
59ad60 |
GPtrArray *summary;
|
|
|
59ad60 |
gint local_data_search = 0, *prev_local_data_search, ii;
|
|
|
59ad60 |
@@ -191,9 +215,9 @@ imapx_search_match_all (CamelSExp *sexp,
|
|
|
59ad60 |
if (argc != 1)
|
|
|
59ad60 |
return imapx_search_result_match_none (sexp, search);
|
|
|
59ad60 |
|
|
|
59ad60 |
- server = camel_imapx_search_ref_server (CAMEL_IMAPX_SEARCH (search));
|
|
|
59ad60 |
- if (!server || search->current || !search->summary) {
|
|
|
59ad60 |
- g_clear_object (&server);
|
|
|
59ad60 |
+ imapx_store = camel_imapx_search_ref_store (CAMEL_IMAPX_SEARCH (search));
|
|
|
59ad60 |
+ if (!imapx_store || search->current || !search->summary) {
|
|
|
59ad60 |
+ g_clear_object (&imapx_store);
|
|
|
59ad60 |
|
|
|
59ad60 |
/* Chain up to parent's method. */
|
|
|
59ad60 |
return CAMEL_FOLDER_SEARCH_CLASS (camel_imapx_search_parent_class)->
|
|
|
59ad60 |
@@ -224,7 +248,7 @@ imapx_search_match_all (CamelSExp *sexp,
|
|
|
59ad60 |
imapx_search->priv->local_data_search = prev_local_data_search;
|
|
|
59ad60 |
|
|
|
59ad60 |
if (local_data_search >= 0) {
|
|
|
59ad60 |
- g_clear_object (&server);
|
|
|
59ad60 |
+ g_clear_object (&imapx_store);
|
|
|
59ad60 |
|
|
|
59ad60 |
/* Chain up to parent's method. */
|
|
|
59ad60 |
return CAMEL_FOLDER_SEARCH_CLASS (camel_imapx_search_parent_class)->
|
|
|
59ad60 |
@@ -235,7 +259,7 @@ imapx_search_match_all (CamelSExp *sexp,
|
|
|
59ad60 |
but here is expected GPtrArray of matched UIDs */
|
|
|
59ad60 |
result = camel_sexp_term_eval (sexp, argv[0]);
|
|
|
59ad60 |
|
|
|
59ad60 |
- g_object_unref (server);
|
|
|
59ad60 |
+ g_clear_object (&imapx_store);
|
|
|
59ad60 |
|
|
|
59ad60 |
g_return_val_if_fail (result != NULL, result);
|
|
|
59ad60 |
g_return_val_if_fail (result->type == CAMEL_SEXP_RES_ARRAY_PTR, result);
|
|
|
59ad60 |
@@ -250,7 +274,7 @@ imapx_search_body_contains (CamelSExp *s
|
|
|
59ad60 |
CamelFolderSearch *search)
|
|
|
59ad60 |
{
|
|
|
59ad60 |
CamelIMAPXSearch *imapx_search = CAMEL_IMAPX_SEARCH (search);
|
|
|
59ad60 |
- CamelIMAPXServer *server;
|
|
|
59ad60 |
+ CamelIMAPXStore *imapx_store;
|
|
|
59ad60 |
CamelSExpResult *result;
|
|
|
59ad60 |
GString *criteria;
|
|
|
59ad60 |
gint ii, jj;
|
|
|
59ad60 |
@@ -269,10 +293,10 @@ imapx_search_body_contains (CamelSExp *s
|
|
|
59ad60 |
if (argc == 0 || search->summary->len == 0)
|
|
|
59ad60 |
return imapx_search_result_match_none (sexp, search);
|
|
|
59ad60 |
|
|
|
59ad60 |
- server = camel_imapx_search_ref_server (CAMEL_IMAPX_SEARCH (search));
|
|
|
59ad60 |
+ imapx_store = camel_imapx_search_ref_store (CAMEL_IMAPX_SEARCH (search));
|
|
|
59ad60 |
|
|
|
59ad60 |
- /* This will be NULL if we're offline. Search from cache. */
|
|
|
59ad60 |
- if (server == NULL) {
|
|
|
59ad60 |
+ /* This will be NULL if we're offline. Search from cache. */
|
|
|
59ad60 |
+ if (imapx_store == NULL) {
|
|
|
59ad60 |
/* Chain up to parent's method. */
|
|
|
59ad60 |
return CAMEL_FOLDER_SEARCH_CLASS (camel_imapx_search_parent_class)->
|
|
|
59ad60 |
body_contains (sexp, argc, argv, search);
|
|
|
59ad60 |
@@ -320,10 +344,10 @@ imapx_search_body_contains (CamelSExp *s
|
|
|
59ad60 |
}
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
- result = imapx_search_process_criteria (sexp, search, server, criteria, G_STRFUNC);
|
|
|
59ad60 |
+ result = imapx_search_process_criteria (sexp, search, imapx_store, criteria, G_STRFUNC);
|
|
|
59ad60 |
|
|
|
59ad60 |
g_string_free (criteria, TRUE);
|
|
|
59ad60 |
- g_object_unref (server);
|
|
|
59ad60 |
+ g_object_unref (imapx_store);
|
|
|
59ad60 |
|
|
|
59ad60 |
return result;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
@@ -344,7 +368,7 @@ imapx_search_header_contains (CamelSExp
|
|
|
59ad60 |
CamelFolderSearch *search)
|
|
|
59ad60 |
{
|
|
|
59ad60 |
CamelIMAPXSearch *imapx_search = CAMEL_IMAPX_SEARCH (search);
|
|
|
59ad60 |
- CamelIMAPXServer *server;
|
|
|
59ad60 |
+ CamelIMAPXStore *imapx_store;
|
|
|
59ad60 |
CamelSExpResult *result;
|
|
|
59ad60 |
const gchar *headername, *command = NULL;
|
|
|
59ad60 |
GString *criteria;
|
|
|
59ad60 |
@@ -373,10 +397,10 @@ imapx_search_header_contains (CamelSExp
|
|
|
59ad60 |
return imapx_search_result_match_none (sexp, search);
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
- server = camel_imapx_search_ref_server (CAMEL_IMAPX_SEARCH (search));
|
|
|
59ad60 |
+ imapx_store = camel_imapx_search_ref_store (CAMEL_IMAPX_SEARCH (search));
|
|
|
59ad60 |
|
|
|
59ad60 |
- /* This will be NULL if we're offline. Search from cache. */
|
|
|
59ad60 |
- if (server == NULL) {
|
|
|
59ad60 |
+ /* This will be NULL if we're offline. Search from cache. */
|
|
|
59ad60 |
+ if (imapx_store == NULL) {
|
|
|
59ad60 |
/* Chain up to parent's method. */
|
|
|
59ad60 |
return CAMEL_FOLDER_SEARCH_CLASS (camel_imapx_search_parent_class)->
|
|
|
59ad60 |
header_contains (sexp, argc, argv, search);
|
|
|
59ad60 |
@@ -440,10 +464,10 @@ imapx_search_header_contains (CamelSExp
|
|
|
59ad60 |
}
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
- result = imapx_search_process_criteria (sexp, search, server, criteria, G_STRFUNC);
|
|
|
59ad60 |
+ result = imapx_search_process_criteria (sexp, search, imapx_store, criteria, G_STRFUNC);
|
|
|
59ad60 |
|
|
|
59ad60 |
g_string_free (criteria, TRUE);
|
|
|
59ad60 |
- g_object_unref (server);
|
|
|
59ad60 |
+ g_object_unref (imapx_store);
|
|
|
59ad60 |
|
|
|
59ad60 |
return result;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
@@ -455,7 +479,7 @@ imapx_search_header_exists (CamelSExp *s
|
|
|
59ad60 |
CamelFolderSearch *search)
|
|
|
59ad60 |
{
|
|
|
59ad60 |
CamelIMAPXSearch *imapx_search = CAMEL_IMAPX_SEARCH (search);
|
|
|
59ad60 |
- CamelIMAPXServer *server;
|
|
|
59ad60 |
+ CamelIMAPXStore *imapx_store;
|
|
|
59ad60 |
CamelSExpResult *result;
|
|
|
59ad60 |
GString *criteria;
|
|
|
59ad60 |
gint ii;
|
|
|
59ad60 |
@@ -490,10 +514,10 @@ imapx_search_header_exists (CamelSExp *s
|
|
|
59ad60 |
return imapx_search_result_match_none (sexp, search);
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
- server = camel_imapx_search_ref_server (CAMEL_IMAPX_SEARCH (search));
|
|
|
59ad60 |
+ imapx_store = camel_imapx_search_ref_store (CAMEL_IMAPX_SEARCH (search));
|
|
|
59ad60 |
|
|
|
59ad60 |
- /* This will be NULL if we're offline. Search from cache. */
|
|
|
59ad60 |
- if (server == NULL) {
|
|
|
59ad60 |
+ /* This will be NULL if we're offline. Search from cache. */
|
|
|
59ad60 |
+ if (imapx_store == NULL) {
|
|
|
59ad60 |
/* Chain up to parent's method. */
|
|
|
59ad60 |
return CAMEL_FOLDER_SEARCH_CLASS (camel_imapx_search_parent_class)->
|
|
|
59ad60 |
header_exists (sexp, argc, argv, search);
|
|
|
59ad60 |
@@ -525,10 +549,10 @@ imapx_search_header_exists (CamelSExp *s
|
|
|
59ad60 |
g_string_append_printf (criteria, "HEADER \"%s\" \"\"", headername);
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
- result = imapx_search_process_criteria (sexp, search, server, criteria, G_STRFUNC);
|
|
|
59ad60 |
+ result = imapx_search_process_criteria (sexp, search, imapx_store, criteria, G_STRFUNC);
|
|
|
59ad60 |
|
|
|
59ad60 |
g_string_free (criteria, TRUE);
|
|
|
59ad60 |
- g_object_unref (server);
|
|
|
59ad60 |
+ g_object_unref (imapx_store);
|
|
|
59ad60 |
|
|
|
59ad60 |
return result;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
@@ -554,12 +578,12 @@ camel_imapx_search_class_init (CamelIMAP
|
|
|
59ad60 |
|
|
|
59ad60 |
g_object_class_install_property (
|
|
|
59ad60 |
object_class,
|
|
|
59ad60 |
- PROP_SERVER,
|
|
|
59ad60 |
+ PROP_STORE,
|
|
|
59ad60 |
g_param_spec_object (
|
|
|
59ad60 |
- "server",
|
|
|
59ad60 |
- "Server",
|
|
|
59ad60 |
- "Server proxy for server-side searches",
|
|
|
59ad60 |
- CAMEL_TYPE_IMAPX_SERVER,
|
|
|
59ad60 |
+ "store",
|
|
|
59ad60 |
+ "IMAPX Store",
|
|
|
59ad60 |
+ "IMAPX Store for server-side searches",
|
|
|
59ad60 |
+ CAMEL_TYPE_IMAPX_STORE,
|
|
|
59ad60 |
G_PARAM_READWRITE |
|
|
|
59ad60 |
G_PARAM_STATIC_STRINGS));
|
|
|
59ad60 |
}
|
|
|
59ad60 |
@@ -573,67 +597,105 @@ camel_imapx_search_init (CamelIMAPXSearc
|
|
|
59ad60 |
|
|
|
59ad60 |
/**
|
|
|
59ad60 |
* camel_imapx_search_new:
|
|
|
59ad60 |
+ * imapx_store: a #CamelIMAPXStore to which the search belongs
|
|
|
59ad60 |
*
|
|
|
59ad60 |
* Returns a new #CamelIMAPXSearch instance.
|
|
|
59ad60 |
*
|
|
|
59ad60 |
- * The #CamelIMAPXSearch must be given a #CamelIMAPXSearch:server before
|
|
|
59ad60 |
- * it can issue server-side search requests. Otherwise it will fallback
|
|
|
59ad60 |
- * to the default #CamelFolderSearch behavior.
|
|
|
59ad60 |
- *
|
|
|
59ad60 |
* Returns: a new #CamelIMAPXSearch
|
|
|
59ad60 |
*
|
|
|
59ad60 |
* Since: 3.8
|
|
|
59ad60 |
**/
|
|
|
59ad60 |
CamelFolderSearch *
|
|
|
59ad60 |
-camel_imapx_search_new (void)
|
|
|
59ad60 |
+camel_imapx_search_new (CamelIMAPXStore *imapx_store)
|
|
|
59ad60 |
{
|
|
|
59ad60 |
- return g_object_new (CAMEL_TYPE_IMAPX_SEARCH, NULL);
|
|
|
59ad60 |
+ g_return_val_if_fail (CAMEL_IS_IMAPX_STORE (imapx_store), NULL);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ return g_object_new (
|
|
|
59ad60 |
+ CAMEL_TYPE_IMAPX_SEARCH,
|
|
|
59ad60 |
+ "store", imapx_store,
|
|
|
59ad60 |
+ NULL);
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
/**
|
|
|
59ad60 |
- * camel_imapx_search_ref_server:
|
|
|
59ad60 |
+ * camel_imapx_search_ref_store:
|
|
|
59ad60 |
* @search: a #CamelIMAPXSearch
|
|
|
59ad60 |
*
|
|
|
59ad60 |
- * Returns a #CamelIMAPXServer to use for server-side searches,
|
|
|
59ad60 |
- * or %NULL when the corresponding #CamelIMAPXStore is offline.
|
|
|
59ad60 |
+ * Returns a #CamelIMAPXStore to use for server-side searches,
|
|
|
59ad60 |
+ * or %NULL when the store is offline.
|
|
|
59ad60 |
*
|
|
|
59ad60 |
- * The returned #CamelIMAPXSearch is referenced for thread-safety and
|
|
|
59ad60 |
+ * The returned #CamelIMAPXStore is referenced for thread-safety and
|
|
|
59ad60 |
* must be unreferenced with g_object_unref() when finished with it.
|
|
|
59ad60 |
*
|
|
|
59ad60 |
- * Returns: a #CamelIMAPXServer, or %NULL
|
|
|
59ad60 |
+ * Returns: a #CamelIMAPXStore, or %NULL
|
|
|
59ad60 |
*
|
|
|
59ad60 |
* Since: 3.8
|
|
|
59ad60 |
**/
|
|
|
59ad60 |
-CamelIMAPXServer *
|
|
|
59ad60 |
-camel_imapx_search_ref_server (CamelIMAPXSearch *search)
|
|
|
59ad60 |
+CamelIMAPXStore *
|
|
|
59ad60 |
+camel_imapx_search_ref_store (CamelIMAPXSearch *search)
|
|
|
59ad60 |
{
|
|
|
59ad60 |
+ CamelIMAPXStore *imapx_store;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
g_return_val_if_fail (CAMEL_IS_IMAPX_SEARCH (search), NULL);
|
|
|
59ad60 |
|
|
|
59ad60 |
- return g_weak_ref_get (&search->priv->server);
|
|
|
59ad60 |
+ imapx_store = g_weak_ref_get (&search->priv->imapx_store);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (imapx_store && !camel_offline_store_get_online (CAMEL_OFFLINE_STORE (imapx_store)))
|
|
|
59ad60 |
+ g_clear_object (&imapx_store);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ return imapx_store;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
/**
|
|
|
59ad60 |
- * camel_imapx_search_set_server:
|
|
|
59ad60 |
+ * camel_imapx_search_set_store:
|
|
|
59ad60 |
* @search: a #CamelIMAPXSearch
|
|
|
59ad60 |
- * @server: a #CamelIMAPXServer, or %NULL
|
|
|
59ad60 |
+ * @imapx_server: a #CamelIMAPXStore, or %NULL
|
|
|
59ad60 |
*
|
|
|
59ad60 |
- * Sets a #CamelIMAPXServer to use for server-side searches. Generally
|
|
|
59ad60 |
+ * Sets a #CamelIMAPXStore to use for server-side searches. Generally
|
|
|
59ad60 |
* this is set for the duration of a single search when online, and then
|
|
|
59ad60 |
* reset to %NULL.
|
|
|
59ad60 |
*
|
|
|
59ad60 |
* Since: 3.8
|
|
|
59ad60 |
**/
|
|
|
59ad60 |
void
|
|
|
59ad60 |
-camel_imapx_search_set_server (CamelIMAPXSearch *search,
|
|
|
59ad60 |
- CamelIMAPXServer *server)
|
|
|
59ad60 |
+camel_imapx_search_set_store (CamelIMAPXSearch *search,
|
|
|
59ad60 |
+ CamelIMAPXStore *imapx_store)
|
|
|
59ad60 |
{
|
|
|
59ad60 |
g_return_if_fail (CAMEL_IS_IMAPX_SEARCH (search));
|
|
|
59ad60 |
|
|
|
59ad60 |
- if (server != NULL)
|
|
|
59ad60 |
- g_return_if_fail (CAMEL_IS_IMAPX_SERVER (server));
|
|
|
59ad60 |
+ if (imapx_store != NULL)
|
|
|
59ad60 |
+ g_return_if_fail (CAMEL_IS_IMAPX_STORE (imapx_store));
|
|
|
59ad60 |
|
|
|
59ad60 |
- g_weak_ref_set (&search->priv->server, server);
|
|
|
59ad60 |
+ g_weak_ref_set (&search->priv->imapx_store, imapx_store);
|
|
|
59ad60 |
|
|
|
59ad60 |
- g_object_notify (G_OBJECT (search), "server");
|
|
|
59ad60 |
+ g_object_notify (G_OBJECT (search), "store");
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
+/**
|
|
|
59ad60 |
+ * camel_imapx_search_set_cancellable_and_error:
|
|
|
59ad60 |
+ * @search: a #CamelIMAPXSearch
|
|
|
59ad60 |
+ * @cancellable: a #GCancellable, or %NULL
|
|
|
59ad60 |
+ * @error: a #GError, or %NULL
|
|
|
59ad60 |
+ *
|
|
|
59ad60 |
+ * Sets @cancellable and @error to use for server-side searches. This way
|
|
|
59ad60 |
+ * the search can return accurate errors and be eventually cancelled by
|
|
|
59ad60 |
+ * a user.
|
|
|
59ad60 |
+ *
|
|
|
59ad60 |
+ * Note: The caller is responsible to keep alive both @cancellable and @error
|
|
|
59ad60 |
+ * for the whole run of the search and reset them both to NULL after
|
|
|
59ad60 |
+ * the search is finished.
|
|
|
59ad60 |
+ *
|
|
|
59ad60 |
+ * Since: 3.14
|
|
|
59ad60 |
+ **/
|
|
|
59ad60 |
+void
|
|
|
59ad60 |
+camel_imapx_search_set_cancellable_and_error (CamelIMAPXSearch *search,
|
|
|
59ad60 |
+ GCancellable *cancellable,
|
|
|
59ad60 |
+ GError **error)
|
|
|
59ad60 |
+{
|
|
|
59ad60 |
+ g_return_if_fail (CAMEL_IS_IMAPX_SEARCH (search));
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (cancellable)
|
|
|
59ad60 |
+ g_return_if_fail (G_IS_CANCELLABLE (cancellable));
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ search->priv->cancellable = cancellable;
|
|
|
59ad60 |
+ search->priv->error = error;
|
|
|
59ad60 |
+}
|
|
|
59ad60 |
diff -up evolution-data-server-3.8.5/camel/camel-imapx-search.h.imapx-conn-manager-ext evolution-data-server-3.8.5/camel/camel-imapx-search.h
|
|
|
59ad60 |
--- evolution-data-server-3.8.5/camel/camel-imapx-search.h.imapx-conn-manager-ext 2013-07-23 13:57:45.000000000 +0200
|
|
|
59ad60 |
+++ evolution-data-server-3.8.5/camel/camel-imapx-search.h 2014-05-13 14:17:43.116983665 +0200
|
|
|
59ad60 |
@@ -24,7 +24,7 @@
|
|
|
59ad60 |
#define CAMEL_IMAPX_SEARCH_H
|
|
|
59ad60 |
|
|
|
59ad60 |
#include <camel/camel-folder-search.h>
|
|
|
59ad60 |
-#include <camel/camel-imapx-server.h>
|
|
|
59ad60 |
+#include <camel/camel-imapx-store.h>
|
|
|
59ad60 |
|
|
|
59ad60 |
/* Standard GObject macros */
|
|
|
59ad60 |
#define CAMEL_TYPE_IMAPX_SEARCH \
|
|
|
59ad60 |
@@ -47,6 +47,9 @@
|
|
|
59ad60 |
|
|
|
59ad60 |
G_BEGIN_DECLS
|
|
|
59ad60 |
|
|
|
59ad60 |
+/* Avoid a circular reference. */
|
|
|
59ad60 |
+struct _CamelIMAPXStore;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
typedef struct _CamelIMAPXSearch CamelIMAPXSearch;
|
|
|
59ad60 |
typedef struct _CamelIMAPXSearchClass CamelIMAPXSearchClass;
|
|
|
59ad60 |
typedef struct _CamelIMAPXSearchPrivate CamelIMAPXSearchPrivate;
|
|
|
59ad60 |
@@ -70,11 +73,15 @@ struct _CamelIMAPXSearchClass {
|
|
|
59ad60 |
|
|
|
59ad60 |
GType camel_imapx_search_get_type (void) G_GNUC_CONST;
|
|
|
59ad60 |
CamelFolderSearch *
|
|
|
59ad60 |
- camel_imapx_search_new (void);
|
|
|
59ad60 |
-CamelIMAPXServer *
|
|
|
59ad60 |
- camel_imapx_search_ref_server (CamelIMAPXSearch *search);
|
|
|
59ad60 |
-void camel_imapx_search_set_server (CamelIMAPXSearch *search,
|
|
|
59ad60 |
- CamelIMAPXServer *server);
|
|
|
59ad60 |
+ camel_imapx_search_new (struct _CamelIMAPXStore *imapx_store);
|
|
|
59ad60 |
+struct _CamelIMAPXStore *
|
|
|
59ad60 |
+ camel_imapx_search_ref_store (CamelIMAPXSearch *search);
|
|
|
59ad60 |
+void camel_imapx_search_set_store (CamelIMAPXSearch *search,
|
|
|
59ad60 |
+ struct _CamelIMAPXStore *imapx_store);
|
|
|
59ad60 |
+void camel_imapx_search_set_cancellable_and_error
|
|
|
59ad60 |
+ (CamelIMAPXSearch *search,
|
|
|
59ad60 |
+ GCancellable *cancellable,
|
|
|
59ad60 |
+ GError **error);
|
|
|
59ad60 |
|
|
|
59ad60 |
G_END_DECLS
|
|
|
59ad60 |
|
|
|
59ad60 |
diff -up evolution-data-server-3.8.5/camel/camel-imapx-server.c.imapx-conn-manager-ext evolution-data-server-3.8.5/camel/camel-imapx-server.c
|
|
|
59ad60 |
--- evolution-data-server-3.8.5/camel/camel-imapx-server.c.imapx-conn-manager-ext 2014-05-13 14:17:43.110983665 +0200
|
|
|
59ad60 |
+++ evolution-data-server-3.8.5/camel/camel-imapx-server.c 2014-05-13 14:17:43.118983665 +0200
|
|
|
59ad60 |
@@ -73,6 +73,8 @@
|
|
|
59ad60 |
|
|
|
59ad60 |
#define MAX_COMMAND_LEN 1000
|
|
|
59ad60 |
|
|
|
59ad60 |
+G_DEFINE_QUARK (camel-imapx-server-error-quark, camel_imapx_server_error)
|
|
|
59ad60 |
+
|
|
|
59ad60 |
extern gint camel_application_is_exiting;
|
|
|
59ad60 |
|
|
|
59ad60 |
/* Job-specific structs */
|
|
|
59ad60 |
@@ -343,6 +345,14 @@ struct _CamelIMAPXServerPrivate {
|
|
|
59ad60 |
|
|
|
59ad60 |
GHashTable *known_alerts;
|
|
|
59ad60 |
GMutex known_alerts_lock;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ GMutex jobs_prop_lock;
|
|
|
59ad60 |
+ GHashTable *jobs_prop_folder_paths;
|
|
|
59ad60 |
+ gint jobs_prop_command_count; /* without IDLE command */
|
|
|
59ad60 |
+ gint jobs_prop_expensive_command_count;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ GMutex shutdown_error_lock;
|
|
|
59ad60 |
+ GError *shutdown_error;
|
|
|
59ad60 |
};
|
|
|
59ad60 |
|
|
|
59ad60 |
enum {
|
|
|
59ad60 |
@@ -377,7 +387,6 @@ static gboolean imapx_continuation (Cam
|
|
|
59ad60 |
gboolean litplus,
|
|
|
59ad60 |
GCancellable *cancellable,
|
|
|
59ad60 |
GError **error);
|
|
|
59ad60 |
-static gboolean imapx_disconnect (CamelIMAPXServer *is);
|
|
|
59ad60 |
static gboolean imapx_is_command_queue_empty (CamelIMAPXServer *is);
|
|
|
59ad60 |
static gint imapx_uid_cmp (gconstpointer ap,
|
|
|
59ad60 |
gconstpointer bp,
|
|
|
59ad60 |
@@ -560,6 +569,159 @@ replace_untagged_descriptor (GHashTable
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
static void
|
|
|
59ad60 |
+imapx_server_set_shutdown_error (CamelIMAPXServer *imapx_server,
|
|
|
59ad60 |
+ const GError *error)
|
|
|
59ad60 |
+{
|
|
|
59ad60 |
+ g_mutex_lock (&imapx_server->priv->shutdown_error_lock);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (error != imapx_server->priv->shutdown_error) {
|
|
|
59ad60 |
+ g_clear_error (&imapx_server->priv->shutdown_error);
|
|
|
59ad60 |
+ if (error)
|
|
|
59ad60 |
+ imapx_server->priv->shutdown_error = g_error_copy (error);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_mutex_unlock (&imapx_server->priv->shutdown_error_lock);
|
|
|
59ad60 |
+}
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+static GError *
|
|
|
59ad60 |
+imapx_server_dup_shutdown_error (CamelIMAPXServer *imapx_server)
|
|
|
59ad60 |
+{
|
|
|
59ad60 |
+ GError *error = NULL;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_mutex_lock (&imapx_server->priv->shutdown_error_lock);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (imapx_server->priv->shutdown_error)
|
|
|
59ad60 |
+ error = g_error_copy (imapx_server->priv->shutdown_error);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_mutex_unlock (&imapx_server->priv->shutdown_error_lock);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ return error;
|
|
|
59ad60 |
+}
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+static void
|
|
|
59ad60 |
+imapx_server_command_added (CamelIMAPXServer *imapx_server,
|
|
|
59ad60 |
+ CamelIMAPXCommand *command)
|
|
|
59ad60 |
+{
|
|
|
59ad60 |
+ CamelIMAPXJob *job;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_return_if_fail (command != NULL);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_mutex_lock (&imapx_server->priv->jobs_prop_lock);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ job = camel_imapx_command_get_job (command);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (job) {
|
|
|
59ad60 |
+ /* without IDLE commands */
|
|
|
59ad60 |
+ if (!(job->type & IMAPX_JOB_IDLE))
|
|
|
59ad60 |
+ imapx_server->priv->jobs_prop_command_count++;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if ((job->type & (IMAPX_JOB_FETCH_NEW_MESSAGES | IMAPX_JOB_REFRESH_INFO)) != 0)
|
|
|
59ad60 |
+ imapx_server->priv->jobs_prop_expensive_command_count++;
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_mutex_unlock (&imapx_server->priv->jobs_prop_lock);
|
|
|
59ad60 |
+}
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+static void
|
|
|
59ad60 |
+imapx_server_command_removed (CamelIMAPXServer *imapx_server,
|
|
|
59ad60 |
+ CamelIMAPXCommand *command)
|
|
|
59ad60 |
+{
|
|
|
59ad60 |
+ CamelIMAPXJob *job;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_return_if_fail (command != NULL);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_mutex_lock (&imapx_server->priv->jobs_prop_lock);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ job = camel_imapx_command_get_job (command);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (job) {
|
|
|
59ad60 |
+ /* without IDLE commands */
|
|
|
59ad60 |
+ if (!(job->type & IMAPX_JOB_IDLE)) {
|
|
|
59ad60 |
+ imapx_server->priv->jobs_prop_command_count--;
|
|
|
59ad60 |
+ g_warn_if_fail (imapx_server->priv->jobs_prop_command_count >= 0);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if ((job->type & (IMAPX_JOB_FETCH_NEW_MESSAGES | IMAPX_JOB_REFRESH_INFO)) != 0) {
|
|
|
59ad60 |
+ imapx_server->priv->jobs_prop_expensive_command_count--;
|
|
|
59ad60 |
+ g_warn_if_fail (imapx_server->priv->jobs_prop_expensive_command_count >= 0);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_mutex_unlock (&imapx_server->priv->jobs_prop_lock);
|
|
|
59ad60 |
+}
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+static void
|
|
|
59ad60 |
+imapx_server_add_job_mailbox (CamelIMAPXServer *imapx_server,
|
|
|
59ad60 |
+ const gchar *folder_path)
|
|
|
59ad60 |
+{
|
|
|
59ad60 |
+ gint n_stored;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_return_if_fail (folder_path != NULL);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_mutex_lock (&imapx_server->priv->jobs_prop_lock);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ n_stored = GPOINTER_TO_INT (g_hash_table_lookup (imapx_server->priv->jobs_prop_folder_paths, folder_path));
|
|
|
59ad60 |
+ g_hash_table_insert (imapx_server->priv->jobs_prop_folder_paths, g_strdup (folder_path), GINT_TO_POINTER (n_stored + 1));
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_mutex_unlock (&imapx_server->priv->jobs_prop_lock);
|
|
|
59ad60 |
+}
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+static void
|
|
|
59ad60 |
+imapx_server_remove_job_mailbox (CamelIMAPXServer *imapx_server,
|
|
|
59ad60 |
+ const gchar *folder_path)
|
|
|
59ad60 |
+{
|
|
|
59ad60 |
+ gint n_stored;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_return_if_fail (folder_path != NULL);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_mutex_lock (&imapx_server->priv->jobs_prop_lock);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ n_stored = GPOINTER_TO_INT (g_hash_table_lookup (imapx_server->priv->jobs_prop_folder_paths, folder_path));
|
|
|
59ad60 |
+ g_warn_if_fail (n_stored >= 1);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ n_stored--;
|
|
|
59ad60 |
+ if (n_stored > 0) {
|
|
|
59ad60 |
+ g_hash_table_insert (imapx_server->priv->jobs_prop_folder_paths, g_strdup (folder_path), GINT_TO_POINTER (n_stored));
|
|
|
59ad60 |
+ } else {
|
|
|
59ad60 |
+ g_hash_table_remove (imapx_server->priv->jobs_prop_folder_paths, folder_path);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_mutex_unlock (&imapx_server->priv->jobs_prop_lock);
|
|
|
59ad60 |
+}
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+static void
|
|
|
59ad60 |
+imapx_server_job_added (CamelIMAPXServer *imapx_server,
|
|
|
59ad60 |
+ CamelIMAPXJob *job)
|
|
|
59ad60 |
+{
|
|
|
59ad60 |
+ CamelFolder *folder;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_return_if_fail (job != NULL);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ folder = camel_imapx_job_ref_folder (job);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (folder != NULL) {
|
|
|
59ad60 |
+ imapx_server_add_job_mailbox (imapx_server, camel_folder_get_full_name (folder));
|
|
|
59ad60 |
+ g_object_unref (folder);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+}
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+static void
|
|
|
59ad60 |
+imapx_server_job_removed (CamelIMAPXServer *imapx_server,
|
|
|
59ad60 |
+ CamelIMAPXJob *job)
|
|
|
59ad60 |
+{
|
|
|
59ad60 |
+ CamelFolder *folder;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_return_if_fail (job != NULL);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ folder = camel_imapx_job_ref_folder (job);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (folder != NULL) {
|
|
|
59ad60 |
+ imapx_server_remove_job_mailbox (imapx_server, camel_folder_get_full_name (folder));
|
|
|
59ad60 |
+ g_object_unref (folder);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+}
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+static void
|
|
|
59ad60 |
add_initial_untagged_descriptor (GHashTable *untagged_handlers,
|
|
|
59ad60 |
guint untagged_id)
|
|
|
59ad60 |
{
|
|
|
59ad60 |
@@ -582,8 +744,8 @@ static GHashTable *
|
|
|
59ad60 |
create_initial_untagged_handler_table (void)
|
|
|
59ad60 |
{
|
|
|
59ad60 |
GHashTable *uh = g_hash_table_new_full (
|
|
|
59ad60 |
- g_str_hash,
|
|
|
59ad60 |
- g_str_equal,
|
|
|
59ad60 |
+ camel_strcase_hash,
|
|
|
59ad60 |
+ camel_strcase_equal,
|
|
|
59ad60 |
g_free,
|
|
|
59ad60 |
NULL);
|
|
|
59ad60 |
guint32 ii = 0;
|
|
|
59ad60 |
@@ -833,12 +995,14 @@ imapx_command_start (CamelIMAPXServer *i
|
|
|
59ad60 |
{
|
|
|
59ad60 |
CamelIMAPXStream *stream = NULL;
|
|
|
59ad60 |
CamelIMAPXCommandPart *cp;
|
|
|
59ad60 |
+ CamelIMAPXJob *job;
|
|
|
59ad60 |
gboolean cp_continuation;
|
|
|
59ad60 |
gboolean cp_literal_plus;
|
|
|
59ad60 |
GList *head;
|
|
|
59ad60 |
gboolean success = FALSE;
|
|
|
59ad60 |
gchar *string;
|
|
|
59ad60 |
gint retval;
|
|
|
59ad60 |
+ GError *local_error = NULL;
|
|
|
59ad60 |
|
|
|
59ad60 |
camel_imapx_command_close (ic);
|
|
|
59ad60 |
|
|
|
59ad60 |
@@ -857,6 +1021,14 @@ imapx_command_start (CamelIMAPXServer *i
|
|
|
59ad60 |
is->literal = ic;
|
|
|
59ad60 |
|
|
|
59ad60 |
camel_imapx_command_queue_push_tail (is->active, ic);
|
|
|
59ad60 |
+ imapx_server_command_added (is, ic);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ job = camel_imapx_command_get_job (ic);
|
|
|
59ad60 |
+ if (job && g_cancellable_set_error_if_cancelled (camel_imapx_job_get_cancellable (job), &local_error)) {
|
|
|
59ad60 |
+ camel_imapx_job_set_error (job, local_error);
|
|
|
59ad60 |
+ g_clear_error (&local_error);
|
|
|
59ad60 |
+ goto err;
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
|
|
|
59ad60 |
stream = camel_imapx_server_ref_stream (is);
|
|
|
59ad60 |
|
|
|
59ad60 |
@@ -898,6 +1070,7 @@ imapx_command_start (CamelIMAPXServer *i
|
|
|
59ad60 |
|
|
|
59ad60 |
err:
|
|
|
59ad60 |
camel_imapx_command_queue_remove (is->active, ic);
|
|
|
59ad60 |
+ imapx_server_command_removed (is, ic);
|
|
|
59ad60 |
|
|
|
59ad60 |
/* HACK: Since we're failing, make sure the command has a status
|
|
|
59ad60 |
* structure and the result code indicates failure, so the
|
|
|
59ad60 |
@@ -1016,6 +1189,7 @@ imapx_command_start_next (CamelIMAPXServ
|
|
|
59ad60 |
|
|
|
59ad60 |
ic = camel_imapx_command_ref (link->data);
|
|
|
59ad60 |
camel_imapx_command_queue_delete_link (is->queue, link);
|
|
|
59ad60 |
+ imapx_server_command_removed (is, ic);
|
|
|
59ad60 |
|
|
|
59ad60 |
success = imapx_command_start (
|
|
|
59ad60 |
is, ic, cancellable, error);
|
|
|
59ad60 |
@@ -1150,6 +1324,7 @@ imapx_command_start_next (CamelIMAPXServ
|
|
|
59ad60 |
|
|
|
59ad60 |
ic = camel_imapx_command_ref (link->data);
|
|
|
59ad60 |
camel_imapx_command_queue_delete_link (is->queue, link);
|
|
|
59ad60 |
+ imapx_server_command_removed (is, ic);
|
|
|
59ad60 |
|
|
|
59ad60 |
success = imapx_command_start (
|
|
|
59ad60 |
is, ic, cancellable, error);
|
|
|
59ad60 |
@@ -1223,6 +1398,7 @@ imapx_command_start_next (CamelIMAPXServ
|
|
|
59ad60 |
|
|
|
59ad60 |
ic = camel_imapx_command_ref (link->data);
|
|
|
59ad60 |
camel_imapx_command_queue_delete_link (is->queue, link);
|
|
|
59ad60 |
+ imapx_server_command_removed (is, ic);
|
|
|
59ad60 |
|
|
|
59ad60 |
success = imapx_command_start (
|
|
|
59ad60 |
is, ic, cancellable, error);
|
|
|
59ad60 |
@@ -1279,7 +1455,7 @@ imapx_command_queue (CamelIMAPXServer *i
|
|
|
59ad60 |
if (is->state == IMAPX_SHUTDOWN) {
|
|
|
59ad60 |
c (is->tagprefix, "refuse to queue job on disconnected server\n");
|
|
|
59ad60 |
g_set_error (
|
|
|
59ad60 |
- error, CAMEL_IMAPX_ERROR, 1,
|
|
|
59ad60 |
+ error, CAMEL_IMAPX_SERVER_ERROR, CAMEL_IMAPX_SERVER_ERROR_TRY_RECONNECT,
|
|
|
59ad60 |
"%s", _("Server disconnected"));
|
|
|
59ad60 |
|
|
|
59ad60 |
QUEUE_UNLOCK (is);
|
|
|
59ad60 |
@@ -1294,6 +1470,7 @@ imapx_command_queue (CamelIMAPXServer *i
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
camel_imapx_command_queue_insert_sorted (is->queue, ic);
|
|
|
59ad60 |
+ imapx_server_command_added (is, ic);
|
|
|
59ad60 |
|
|
|
59ad60 |
success = imapx_command_start_next (is, cancellable, error);
|
|
|
59ad60 |
|
|
|
59ad60 |
@@ -1376,38 +1553,34 @@ imapx_match_active_job (CamelIMAPXServer
|
|
|
59ad60 |
return match;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
+/* Do *not* call this when the queue_lock is held, it can cause
|
|
|
59ad60 |
+ deadlock when searching between multiple servers */
|
|
|
59ad60 |
static CamelIMAPXJob *
|
|
|
59ad60 |
-imapx_is_job_in_queue (CamelIMAPXServer *is,
|
|
|
59ad60 |
- CamelFolder *folder,
|
|
|
59ad60 |
- guint32 type,
|
|
|
59ad60 |
- const gchar *uid)
|
|
|
59ad60 |
+imapx_server_ref_job (CamelIMAPXServer *imapx_server,
|
|
|
59ad60 |
+ CamelFolder *folder,
|
|
|
59ad60 |
+ guint32 job_type,
|
|
|
59ad60 |
+ const gchar *uid)
|
|
|
59ad60 |
{
|
|
|
59ad60 |
- GList *head, *link;
|
|
|
59ad60 |
- CamelIMAPXJob *job = NULL;
|
|
|
59ad60 |
- gboolean found = FALSE;
|
|
|
59ad60 |
-
|
|
|
59ad60 |
- QUEUE_LOCK (is);
|
|
|
59ad60 |
+ CamelIMAPXStore *imapx_store;
|
|
|
59ad60 |
+ CamelIMAPXJob *job;
|
|
|
59ad60 |
|
|
|
59ad60 |
- head = g_queue_peek_head_link (&is->jobs);
|
|
|
59ad60 |
+ g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (imapx_server), NULL);
|
|
|
59ad60 |
|
|
|
59ad60 |
- for (link = head; link != NULL; link = g_list_next (link)) {
|
|
|
59ad60 |
- job = (CamelIMAPXJob *) link->data;
|
|
|
59ad60 |
+ /* first try its own queue */
|
|
|
59ad60 |
+ job = camel_imapx_server_ref_job (imapx_server, folder, job_type, uid);
|
|
|
59ad60 |
+ if (job)
|
|
|
59ad60 |
+ return job;
|
|
|
59ad60 |
|
|
|
59ad60 |
- if (!job || !(job->type & type))
|
|
|
59ad60 |
- continue;
|
|
|
59ad60 |
+ /* then try queue for all the opened servers */
|
|
|
59ad60 |
+ imapx_store = camel_imapx_server_ref_store (imapx_server);
|
|
|
59ad60 |
+ if (!imapx_store)
|
|
|
59ad60 |
+ return NULL;
|
|
|
59ad60 |
|
|
|
59ad60 |
- if (camel_imapx_job_matches (job, folder, uid)) {
|
|
|
59ad60 |
- found = TRUE;
|
|
|
59ad60 |
- break;
|
|
|
59ad60 |
- }
|
|
|
59ad60 |
- }
|
|
|
59ad60 |
+ job = camel_imapx_store_ref_job (imapx_store, folder, job_type, uid);
|
|
|
59ad60 |
|
|
|
59ad60 |
- QUEUE_UNLOCK (is);
|
|
|
59ad60 |
+ g_object_unref (imapx_store);
|
|
|
59ad60 |
|
|
|
59ad60 |
- if (found)
|
|
|
59ad60 |
- return job;
|
|
|
59ad60 |
- else
|
|
|
59ad60 |
- return NULL;
|
|
|
59ad60 |
+ return job;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
static void
|
|
|
59ad60 |
@@ -1867,8 +2040,8 @@ imapx_untagged_fetch (CamelIMAPXServer *
|
|
|
59ad60 |
is->changes = camel_folder_change_info_new ();
|
|
|
59ad60 |
|
|
|
59ad60 |
camel_folder_change_info_change_uid (is->changes, uid);
|
|
|
59ad60 |
- g_free (uid);
|
|
|
59ad60 |
}
|
|
|
59ad60 |
+ g_free (uid);
|
|
|
59ad60 |
|
|
|
59ad60 |
if (imapx_idle_supported (is) && changed && imapx_in_idle (is)) {
|
|
|
59ad60 |
camel_folder_summary_save_to_db (
|
|
|
59ad60 |
@@ -2313,9 +2486,6 @@ imapx_untagged_bye (CamelIMAPXServer *is
|
|
|
59ad60 |
GCancellable *cancellable,
|
|
|
59ad60 |
GError **error)
|
|
|
59ad60 |
{
|
|
|
59ad60 |
- CamelIMAPXStore *imapx_store;
|
|
|
59ad60 |
- CamelService *service;
|
|
|
59ad60 |
- CamelServiceConnectionStatus status;
|
|
|
59ad60 |
guchar *token = NULL;
|
|
|
59ad60 |
|
|
|
59ad60 |
g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (is), FALSE);
|
|
|
59ad60 |
@@ -2325,7 +2495,7 @@ imapx_untagged_bye (CamelIMAPXServer *is
|
|
|
59ad60 |
if (camel_imapx_stream_text (stream, &token, cancellable, NULL)) {
|
|
|
59ad60 |
c (is->tagprefix, "BYE: %s\n", token);
|
|
|
59ad60 |
g_set_error (
|
|
|
59ad60 |
- error, CAMEL_IMAPX_ERROR, 1,
|
|
|
59ad60 |
+ error, CAMEL_IMAPX_SERVER_ERROR, CAMEL_IMAPX_SERVER_ERROR_TRY_RECONNECT,
|
|
|
59ad60 |
"IMAP server said BYE: %s", token);
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
@@ -2333,19 +2503,6 @@ imapx_untagged_bye (CamelIMAPXServer *is
|
|
|
59ad60 |
|
|
|
59ad60 |
is->state = IMAPX_SHUTDOWN;
|
|
|
59ad60 |
|
|
|
59ad60 |
- imapx_store = camel_imapx_server_ref_store (is);
|
|
|
59ad60 |
- service = CAMEL_SERVICE (imapx_store);
|
|
|
59ad60 |
- status = camel_service_get_connection_status (service);
|
|
|
59ad60 |
-
|
|
|
59ad60 |
- /* Do not disconnect the service if we're still connecting.
|
|
|
59ad60 |
- * camel_service_disconnect_sync() will cancel the connect
|
|
|
59ad60 |
- * operation and the server message will get replaced with
|
|
|
59ad60 |
- * a generic "Operation was cancelled" message. */
|
|
|
59ad60 |
- if (status == CAMEL_SERVICE_CONNECTED)
|
|
|
59ad60 |
- camel_service_disconnect_sync (service, FALSE, NULL, NULL);
|
|
|
59ad60 |
-
|
|
|
59ad60 |
- g_object_unref (imapx_store);
|
|
|
59ad60 |
-
|
|
|
59ad60 |
return FALSE;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
@@ -2399,10 +2556,16 @@ imapx_untagged_ok_no_bad (CamelIMAPXServ
|
|
|
59ad60 |
select_folder = g_weak_ref_get (&is->select_folder);
|
|
|
59ad60 |
select_pending = g_weak_ref_get (&is->select_pending);
|
|
|
59ad60 |
|
|
|
59ad60 |
- if (select_folder == NULL)
|
|
|
59ad60 |
+ if (select_folder)
|
|
|
59ad60 |
+ imapx_server_remove_job_mailbox (is, camel_folder_get_full_name (select_folder));
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (select_folder == NULL) {
|
|
|
59ad60 |
g_weak_ref_set (
|
|
|
59ad60 |
&is->select_folder,
|
|
|
59ad60 |
select_pending);
|
|
|
59ad60 |
+ if (select_pending)
|
|
|
59ad60 |
+ imapx_server_add_job_mailbox (is, camel_folder_get_full_name (select_pending));
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
|
|
|
59ad60 |
g_clear_object (&select_folder);
|
|
|
59ad60 |
g_clear_object (&select_pending);
|
|
|
59ad60 |
@@ -2849,6 +3012,7 @@ imapx_completion (CamelIMAPXServer *is,
|
|
|
59ad60 |
|
|
|
59ad60 |
camel_imapx_command_ref (ic);
|
|
|
59ad60 |
camel_imapx_command_queue_remove (is->active, ic);
|
|
|
59ad60 |
+ imapx_server_command_removed (is, ic);
|
|
|
59ad60 |
camel_imapx_command_queue_push_tail (is->done, ic);
|
|
|
59ad60 |
camel_imapx_command_unref (ic);
|
|
|
59ad60 |
|
|
|
59ad60 |
@@ -3058,10 +3222,18 @@ imapx_register_job (CamelIMAPXServer *is
|
|
|
59ad60 |
if (is->state >= IMAPX_INITIALISED) {
|
|
|
59ad60 |
QUEUE_LOCK (is);
|
|
|
59ad60 |
g_queue_push_head (&is->jobs, camel_imapx_job_ref (job));
|
|
|
59ad60 |
+ imapx_server_job_added (is, job);
|
|
|
59ad60 |
QUEUE_UNLOCK (is);
|
|
|
59ad60 |
|
|
|
59ad60 |
+ } else if (is->state <= IMAPX_SHUTDOWN) {
|
|
|
59ad60 |
+ e (is->tagprefix, "Server is shutdown/disconnected, try reconnect.");
|
|
|
59ad60 |
+ g_set_error (error,
|
|
|
59ad60 |
+ CAMEL_IMAPX_SERVER_ERROR, CAMEL_IMAPX_SERVER_ERROR_TRY_RECONNECT,
|
|
|
59ad60 |
+ _("Not authenticated"));
|
|
|
59ad60 |
+ return FALSE;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
} else {
|
|
|
59ad60 |
- e (is->tagprefix, "NO connection yet, maybe user cancelled jobs earlier ?");
|
|
|
59ad60 |
+ e (is->tagprefix, "Not connected yet, maybe user cancelled jobs earlier?");
|
|
|
59ad60 |
g_set_error (
|
|
|
59ad60 |
error, CAMEL_SERVICE_ERROR,
|
|
|
59ad60 |
CAMEL_SERVICE_ERROR_NOT_CONNECTED,
|
|
|
59ad60 |
@@ -3080,8 +3252,10 @@ imapx_unregister_job (CamelIMAPXServer *
|
|
|
59ad60 |
camel_imapx_job_done (job);
|
|
|
59ad60 |
|
|
|
59ad60 |
QUEUE_LOCK (is);
|
|
|
59ad60 |
- if (g_queue_remove (&is->jobs, job))
|
|
|
59ad60 |
+ if (g_queue_remove (&is->jobs, job)) {
|
|
|
59ad60 |
+ imapx_server_job_removed (is, job);
|
|
|
59ad60 |
camel_imapx_job_unref (job);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
QUEUE_UNLOCK (is);
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
@@ -3152,6 +3326,7 @@ imapx_command_idle_done (CamelIMAPXServe
|
|
|
59ad60 |
IDLE_UNLOCK (idle);
|
|
|
59ad60 |
|
|
|
59ad60 |
imapx_unregister_job (is, job);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
camel_imapx_command_unref (ic);
|
|
|
59ad60 |
|
|
|
59ad60 |
return success;
|
|
|
59ad60 |
@@ -3347,8 +3522,11 @@ imapx_idle_thread (gpointer data)
|
|
|
59ad60 |
break;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
+ IDLE_LOCK (is->idle);
|
|
|
59ad60 |
g_clear_error (&local_error);
|
|
|
59ad60 |
is->idle->idle_thread = NULL;
|
|
|
59ad60 |
+ IDLE_UNLOCK (is->idle);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
return NULL;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
@@ -3521,6 +3699,11 @@ imapx_command_select_done (CamelIMAPXSer
|
|
|
59ad60 |
c (is->tagprefix, "Select failed\n");
|
|
|
59ad60 |
|
|
|
59ad60 |
g_mutex_lock (&is->select_lock);
|
|
|
59ad60 |
+ folder = g_weak_ref_get (&is->select_folder);
|
|
|
59ad60 |
+ if (folder) {
|
|
|
59ad60 |
+ imapx_server_remove_job_mailbox (is, camel_folder_get_full_name (folder));
|
|
|
59ad60 |
+ g_object_unref (folder);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
folder = g_weak_ref_get (&is->select_pending);
|
|
|
59ad60 |
g_weak_ref_set (&is->select_folder, NULL);
|
|
|
59ad60 |
g_weak_ref_set (&is->select_pending, NULL);
|
|
|
59ad60 |
@@ -3548,7 +3731,9 @@ imapx_command_select_done (CamelIMAPXSer
|
|
|
59ad60 |
|
|
|
59ad60 |
while ((link = g_queue_pop_head (&trash)) != NULL) {
|
|
|
59ad60 |
CamelIMAPXCommand *cw = link->data;
|
|
|
59ad60 |
+ camel_imapx_command_ref (cw);
|
|
|
59ad60 |
camel_imapx_command_queue_delete_link (is->queue, link);
|
|
|
59ad60 |
+ imapx_server_command_removed (is, cw);
|
|
|
59ad60 |
g_queue_push_tail (&failed, cw);
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
@@ -3563,6 +3748,7 @@ imapx_command_select_done (CamelIMAPXSer
|
|
|
59ad60 |
|
|
|
59ad60 |
if (!CAMEL_IS_IMAPX_JOB (job)) {
|
|
|
59ad60 |
g_warn_if_reached ();
|
|
|
59ad60 |
+ camel_imapx_command_unref (cw);
|
|
|
59ad60 |
continue;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
@@ -3572,6 +3758,7 @@ imapx_command_select_done (CamelIMAPXSer
|
|
|
59ad60 |
cw->status = imapx_copy_status (ic->status);
|
|
|
59ad60 |
|
|
|
59ad60 |
cw->complete (is, cw, NULL, NULL);
|
|
|
59ad60 |
+ camel_imapx_command_unref (cw);
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
g_propagate_error (error, local_error);
|
|
|
59ad60 |
@@ -3601,22 +3788,16 @@ imapx_command_select_done (CamelIMAPXSer
|
|
|
59ad60 |
/* We don't want to fetch new messages if the command we selected this
|
|
|
59ad60 |
* folder for is *already* fetching all messages (i.e. scan_changes).
|
|
|
59ad60 |
* Bug #667725. */
|
|
|
59ad60 |
- CamelIMAPXJob *job = imapx_is_job_in_queue (
|
|
|
59ad60 |
+ CamelIMAPXJob *job = imapx_server_ref_job (
|
|
|
59ad60 |
is, folder, IMAPX_JOB_REFRESH_INFO, NULL);
|
|
|
59ad60 |
if (job) {
|
|
|
59ad60 |
- RefreshInfoData *data = camel_imapx_job_get_data (job);
|
|
|
59ad60 |
-
|
|
|
59ad60 |
- if (data->scan_changes) {
|
|
|
59ad60 |
- c (is->tagprefix, "Will not fetch_new_messages when already in scan_changes\n");
|
|
|
59ad60 |
- goto no_fetch_new;
|
|
|
59ad60 |
- }
|
|
|
59ad60 |
+ camel_imapx_job_unref (job);
|
|
|
59ad60 |
+ c (
|
|
|
59ad60 |
+ is->tagprefix,
|
|
|
59ad60 |
+ "Will not fetch_new_messages when already refreshing information\n");
|
|
|
59ad60 |
+ } else {
|
|
|
59ad60 |
+ imapx_server_fetch_new_messages (is, folder, TRUE, TRUE, NULL, NULL);
|
|
|
59ad60 |
}
|
|
|
59ad60 |
- imapx_server_fetch_new_messages (is, folder, TRUE, TRUE, NULL, NULL);
|
|
|
59ad60 |
- /* We don't do this right now because we want the new messages to
|
|
|
59ad60 |
- * update the unseen count. */
|
|
|
59ad60 |
- //ifolder->uidnext_on_server = is->uidnext;
|
|
|
59ad60 |
- no_fetch_new:
|
|
|
59ad60 |
- ;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
ifolder->uidvalidity_on_server = is->uidvalidity;
|
|
|
59ad60 |
selected_folder = camel_folder_get_full_name (folder);
|
|
|
59ad60 |
@@ -3638,6 +3819,9 @@ imapx_command_select_done (CamelIMAPXSer
|
|
|
59ad60 |
|
|
|
59ad60 |
camel_imapx_command_unref (ic);
|
|
|
59ad60 |
|
|
|
59ad60 |
+ if (selected_folder)
|
|
|
59ad60 |
+ imapx_server_add_job_mailbox (is, selected_folder);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
g_signal_emit (is, signals[SELECT_CHANGED], 0, selected_folder);
|
|
|
59ad60 |
|
|
|
59ad60 |
return success;
|
|
|
59ad60 |
@@ -4132,7 +4316,7 @@ camel_imapx_server_authenticate (CamelIM
|
|
|
59ad60 |
|
|
|
59ad60 |
g_return_val_if_fail (
|
|
|
59ad60 |
CAMEL_IS_IMAPX_SERVER (is),
|
|
|
59ad60 |
- CAMEL_AUTHENTICATION_REJECTED);
|
|
|
59ad60 |
+ CAMEL_AUTHENTICATION_ERROR);
|
|
|
59ad60 |
|
|
|
59ad60 |
store = camel_imapx_server_ref_store (is);
|
|
|
59ad60 |
|
|
|
59ad60 |
@@ -4202,8 +4386,27 @@ camel_imapx_server_authenticate (CamelIM
|
|
|
59ad60 |
result = CAMEL_AUTHENTICATION_ERROR;
|
|
|
59ad60 |
else if (ic->status->result == IMAPX_OK)
|
|
|
59ad60 |
result = CAMEL_AUTHENTICATION_ACCEPTED;
|
|
|
59ad60 |
- else
|
|
|
59ad60 |
- result = CAMEL_AUTHENTICATION_REJECTED;
|
|
|
59ad60 |
+ else if (ic->status->result == IMAPX_NO) {
|
|
|
59ad60 |
+ if (camel_imapx_store_get_authenticating_concurrent_connection (store)) {
|
|
|
59ad60 |
+ /* At least one connection succeeded, probably max connection limit
|
|
|
59ad60 |
+ set on the server had been reached, thus use special error code
|
|
|
59ad60 |
+ for it, to instruct the connection manager to decrease the limit
|
|
|
59ad60 |
+ and use already created connection. */
|
|
|
59ad60 |
+ g_set_error_literal (
|
|
|
59ad60 |
+ error, CAMEL_IMAPX_SERVER_ERROR,
|
|
|
59ad60 |
+ CAMEL_IMAPX_SERVER_ERROR_CONCURRENT_CONNECT_FAILED,
|
|
|
59ad60 |
+ ic->status->text ? ic->status->text : _("Unknown error"));
|
|
|
59ad60 |
+ result = CAMEL_AUTHENTICATION_ERROR;
|
|
|
59ad60 |
+ } else {
|
|
|
59ad60 |
+ result = CAMEL_AUTHENTICATION_REJECTED;
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+ } else {
|
|
|
59ad60 |
+ g_set_error_literal (
|
|
|
59ad60 |
+ error, CAMEL_SERVICE_ERROR,
|
|
|
59ad60 |
+ CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE,
|
|
|
59ad60 |
+ ic->status->text ? ic->status->text : _("Unknown error"));
|
|
|
59ad60 |
+ result = CAMEL_AUTHENTICATION_ERROR;
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
|
|
|
59ad60 |
/* Forget old capabilities after login. */
|
|
|
59ad60 |
if (result == CAMEL_AUTHENTICATION_ACCEPTED) {
|
|
|
59ad60 |
@@ -4348,7 +4551,7 @@ imapx_reconnect (CamelIMAPXServer *is,
|
|
|
59ad60 |
|
|
|
59ad60 |
exception:
|
|
|
59ad60 |
|
|
|
59ad60 |
- imapx_disconnect (is);
|
|
|
59ad60 |
+ camel_imapx_server_disconnect (is);
|
|
|
59ad60 |
|
|
|
59ad60 |
if (is->cinfo) {
|
|
|
59ad60 |
imapx_free_capability (is->cinfo);
|
|
|
59ad60 |
@@ -4457,6 +4660,13 @@ imapx_command_fetch_message_done (CamelI
|
|
|
59ad60 |
_("Failed to close the tmp stream"));
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
+ if (success && g_cancellable_set_error_if_cancelled (cancellable, error)) {
|
|
|
59ad60 |
+ success = FALSE;
|
|
|
59ad60 |
+ g_prefix_error (
|
|
|
59ad60 |
+ error, "%s: ",
|
|
|
59ad60 |
+ _("Error fetching message"));
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
if (success) {
|
|
|
59ad60 |
gchar *cur_filename;
|
|
|
59ad60 |
gchar *tmp_filename;
|
|
|
59ad60 |
@@ -5488,7 +5698,6 @@ imapx_job_fetch_new_messages_start (Came
|
|
|
59ad60 |
_("Fetching summary information for new messages in '%s'"),
|
|
|
59ad60 |
camel_folder_get_display_name (folder));
|
|
|
59ad60 |
|
|
|
59ad60 |
- //printf ("Fetch order: %d/%d\n", fetch_order, CAMEL_SORT_DESCENDING);
|
|
|
59ad60 |
if (diff > uidset_size || fetch_order == CAMEL_SORT_DESCENDING) {
|
|
|
59ad60 |
ic = camel_imapx_command_new (
|
|
|
59ad60 |
is, "FETCH", folder,
|
|
|
59ad60 |
@@ -6837,7 +7046,7 @@ imapx_job_sync_changes_matches (CamelIMA
|
|
|
59ad60 |
/* we cancel all the commands and their jobs, so associated jobs will be notified */
|
|
|
59ad60 |
static void
|
|
|
59ad60 |
cancel_all_jobs (CamelIMAPXServer *is,
|
|
|
59ad60 |
- GError *error)
|
|
|
59ad60 |
+ const GError *error)
|
|
|
59ad60 |
{
|
|
|
59ad60 |
CamelIMAPXCommandQueue *queue;
|
|
|
59ad60 |
GList *head, *link;
|
|
|
59ad60 |
@@ -6847,11 +7056,21 @@ cancel_all_jobs (CamelIMAPXServer *is,
|
|
|
59ad60 |
|
|
|
59ad60 |
queue = camel_imapx_command_queue_new ();
|
|
|
59ad60 |
|
|
|
59ad60 |
+ imapx_server_set_shutdown_error (is, error);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
QUEUE_LOCK (is);
|
|
|
59ad60 |
|
|
|
59ad60 |
camel_imapx_command_queue_transfer (is->queue, queue);
|
|
|
59ad60 |
camel_imapx_command_queue_transfer (is->active, queue);
|
|
|
59ad60 |
|
|
|
59ad60 |
+ head = camel_imapx_command_queue_peek_head_link (queue);
|
|
|
59ad60 |
+ for (link = head; link != NULL; link = g_list_next (link)) {
|
|
|
59ad60 |
+ CamelIMAPXCommand *ic = link->data;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (ic)
|
|
|
59ad60 |
+ imapx_server_command_removed (is, ic);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
QUEUE_UNLOCK (is);
|
|
|
59ad60 |
|
|
|
59ad60 |
head = camel_imapx_command_queue_peek_head_link (queue);
|
|
|
59ad60 |
@@ -6871,7 +7090,14 @@ cancel_all_jobs (CamelIMAPXServer *is,
|
|
|
59ad60 |
if (!CAMEL_IS_IMAPX_JOB (job))
|
|
|
59ad60 |
continue;
|
|
|
59ad60 |
|
|
|
59ad60 |
- camel_imapx_job_cancel (job);
|
|
|
59ad60 |
+ if (error) {
|
|
|
59ad60 |
+ /* Insert an error into the CamelIMAPXCommand to be
|
|
|
59ad60 |
+ * propagated when the completion callback function
|
|
|
59ad60 |
+ * calls camel_imapx_command_set_error_if_failed(). */
|
|
|
59ad60 |
+ camel_imapx_job_set_error (job, error);
|
|
|
59ad60 |
+ } else {
|
|
|
59ad60 |
+ camel_imapx_job_cancel (job);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
|
|
|
59ad60 |
/* Send a NULL GError since we already cancelled
|
|
|
59ad60 |
* the job and we're not interested in individual
|
|
|
59ad60 |
@@ -6916,6 +7142,7 @@ imapx_parser_thread (gpointer d)
|
|
|
59ad60 |
GCancellable *cancellable;
|
|
|
59ad60 |
gboolean have_stream;
|
|
|
59ad60 |
GError *local_error = NULL;
|
|
|
59ad60 |
+ GError *shutdown_error;
|
|
|
59ad60 |
|
|
|
59ad60 |
QUEUE_LOCK (is);
|
|
|
59ad60 |
/* Do not use CamelOperation here, because it can be cancelled at
|
|
|
59ad60 |
@@ -6991,8 +7218,28 @@ imapx_parser_thread (gpointer d)
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
/* Jump out of the loop if an error occurred. */
|
|
|
59ad60 |
- if (local_error != NULL)
|
|
|
59ad60 |
+ if (local_error != NULL) {
|
|
|
59ad60 |
+ camel_imapx_debug (io, is->tagprefix, "Data read failed with error '%s'\n", local_error->message);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ /* Sadly, G_IO_ERROR_FAILED is also used for 'Connection reset by peer' error */
|
|
|
59ad60 |
+ if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_FAILED)) {
|
|
|
59ad60 |
+ local_error->domain = CAMEL_IMAPX_SERVER_ERROR;
|
|
|
59ad60 |
+ local_error->code = CAMEL_IMAPX_SERVER_ERROR_TRY_RECONNECT;
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ imapx_server_set_shutdown_error (is, local_error);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ /* Call the signal early, certain thread interleaving can cause the closed connection
|
|
|
59ad60 |
+ being reused on the following reconnect attempt. There is also re-setting
|
|
|
59ad60 |
+ the shutdown_error above, because the signal handler in connection manager
|
|
|
59ad60 |
+ also calls camel_imapx_server_shutdown(), but without the error, while we want
|
|
|
59ad60 |
+ to have there propagated the "try reconnect" error instead. As there is no
|
|
|
59ad60 |
+ guarantee that it'll be called, then we also quit the parser's mainloop and
|
|
|
59ad60 |
+ call the imapx_abort_all_commands() below - just in case. */
|
|
|
59ad60 |
+ g_signal_emit (is, signals[SHUTDOWN], 0, local_error);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
break;
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
|
|
|
59ad60 |
stream = camel_imapx_server_ref_stream (is);
|
|
|
59ad60 |
if (stream != NULL) {
|
|
|
59ad60 |
@@ -7020,7 +7267,12 @@ imapx_parser_thread (gpointer d)
|
|
|
59ad60 |
QUEUE_UNLOCK (is);
|
|
|
59ad60 |
|
|
|
59ad60 |
is->parser_quit = FALSE;
|
|
|
59ad60 |
- g_signal_emit (is, signals[SHUTDOWN], 0);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ shutdown_error = imapx_server_dup_shutdown_error (is);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_signal_emit (is, signals[SHUTDOWN], 0, shutdown_error);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_clear_error (&shutdown_error);
|
|
|
59ad60 |
|
|
|
59ad60 |
g_object_unref (is);
|
|
|
59ad60 |
|
|
|
59ad60 |
@@ -7103,7 +7355,7 @@ imapx_server_dispose (GObject *object)
|
|
|
59ad60 |
if (server->cinfo && imapx_idle_supported (server))
|
|
|
59ad60 |
imapx_exit_idle (server);
|
|
|
59ad60 |
|
|
|
59ad60 |
- imapx_disconnect (server);
|
|
|
59ad60 |
+ camel_imapx_server_disconnect (server);
|
|
|
59ad60 |
|
|
|
59ad60 |
g_weak_ref_set (&server->priv->store, NULL);
|
|
|
59ad60 |
|
|
|
59ad60 |
@@ -7141,6 +7393,12 @@ imapx_server_finalize (GObject *object)
|
|
|
59ad60 |
g_hash_table_destroy (is->priv->known_alerts);
|
|
|
59ad60 |
g_mutex_clear (&is->priv->known_alerts_lock);
|
|
|
59ad60 |
|
|
|
59ad60 |
+ g_mutex_clear (&is->priv->jobs_prop_lock);
|
|
|
59ad60 |
+ g_hash_table_destroy (is->priv->jobs_prop_folder_paths);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_mutex_clear (&is->priv->shutdown_error_lock);
|
|
|
59ad60 |
+ g_clear_error (&is->priv->shutdown_error);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
/* Chain up to parent's finalize() method. */
|
|
|
59ad60 |
G_OBJECT_CLASS (camel_imapx_server_parent_class)->finalize (object);
|
|
|
59ad60 |
}
|
|
|
59ad60 |
@@ -7216,6 +7474,7 @@ camel_imapx_server_class_init (CamelIMAP
|
|
|
59ad60 |
/**
|
|
|
59ad60 |
* CamelIMAPXServer::shutdown
|
|
|
59ad60 |
* @server: the #CamelIMAPXServer which emitted the signal
|
|
|
59ad60 |
+ * @error: a #GError, which caused the shutdown; can be %NULL
|
|
|
59ad60 |
**/
|
|
|
59ad60 |
signals[SHUTDOWN] = g_signal_new (
|
|
|
59ad60 |
"shutdown",
|
|
|
59ad60 |
@@ -7223,8 +7482,8 @@ camel_imapx_server_class_init (CamelIMAP
|
|
|
59ad60 |
G_SIGNAL_RUN_FIRST,
|
|
|
59ad60 |
G_STRUCT_OFFSET (CamelIMAPXServerClass, shutdown),
|
|
|
59ad60 |
NULL, NULL,
|
|
|
59ad60 |
- g_cclosure_marshal_VOID__VOID,
|
|
|
59ad60 |
- G_TYPE_NONE, 0);
|
|
|
59ad60 |
+ g_cclosure_marshal_VOID__BOXED,
|
|
|
59ad60 |
+ G_TYPE_NONE, 1, G_TYPE_ERROR);
|
|
|
59ad60 |
|
|
|
59ad60 |
class->tagprefix = 'A';
|
|
|
59ad60 |
}
|
|
|
59ad60 |
@@ -7239,6 +7498,12 @@ camel_imapx_server_init (CamelIMAPXServe
|
|
|
59ad60 |
g_mutex_init (&is->priv->stream_lock);
|
|
|
59ad60 |
g_mutex_init (&is->priv->search_results_lock);
|
|
|
59ad60 |
g_mutex_init (&is->priv->known_alerts_lock);
|
|
|
59ad60 |
+ g_mutex_init (&is->priv->jobs_prop_lock);
|
|
|
59ad60 |
+ g_mutex_init (&is->priv->shutdown_error_lock);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ is->priv->jobs_prop_folder_paths = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
|
|
59ad60 |
+ is->priv->jobs_prop_command_count = 0;
|
|
|
59ad60 |
+ is->priv->jobs_prop_expensive_command_count = 0;
|
|
|
59ad60 |
|
|
|
59ad60 |
is->queue = camel_imapx_command_queue_new ();
|
|
|
59ad60 |
is->active = camel_imapx_command_queue_new ();
|
|
|
59ad60 |
@@ -7259,6 +7524,8 @@ camel_imapx_server_init (CamelIMAPXServe
|
|
|
59ad60 |
is->changes = camel_folder_change_info_new ();
|
|
|
59ad60 |
is->parser_quit = FALSE;
|
|
|
59ad60 |
|
|
|
59ad60 |
+ is->priv->shutdown_error = NULL;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
is->priv->known_alerts = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
@@ -7312,11 +7579,23 @@ camel_imapx_server_ref_stream (CamelIMAP
|
|
|
59ad60 |
return stream;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
-static gboolean
|
|
|
59ad60 |
-imapx_disconnect (CamelIMAPXServer *is)
|
|
|
59ad60 |
+gboolean
|
|
|
59ad60 |
+camel_imapx_server_disconnect (CamelIMAPXServer *is)
|
|
|
59ad60 |
{
|
|
|
59ad60 |
gboolean ret = TRUE;
|
|
|
59ad60 |
|
|
|
59ad60 |
+ /*QUEUE_LOCK (is);
|
|
|
59ad60 |
+ is->state = IMAPX_SHUTDOWN;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ is->parser_quit = TRUE;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (is->cancellable != NULL) {
|
|
|
59ad60 |
+ g_cancellable_cancel (is->cancellable);
|
|
|
59ad60 |
+ g_object_unref (is->cancellable);
|
|
|
59ad60 |
+ is->cancellable = NULL;
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+ QUEUE_UNLOCK (is);*/
|
|
|
59ad60 |
+
|
|
|
59ad60 |
g_mutex_lock (&is->priv->stream_lock);
|
|
|
59ad60 |
|
|
|
59ad60 |
if (is->priv->stream != NULL) {
|
|
|
59ad60 |
@@ -7387,18 +7666,15 @@ imapx_server_get_message (CamelIMAPXServ
|
|
|
59ad60 |
gboolean registered;
|
|
|
59ad60 |
gboolean success;
|
|
|
59ad60 |
|
|
|
59ad60 |
- QUEUE_LOCK (is);
|
|
|
59ad60 |
-
|
|
|
59ad60 |
- if ((job = imapx_is_job_in_queue (is, folder, IMAPX_JOB_GET_MESSAGE, uid))) {
|
|
|
59ad60 |
+ if ((job = imapx_server_ref_job (is, folder, IMAPX_JOB_GET_MESSAGE, uid))) {
|
|
|
59ad60 |
/* Promote the existing GET_MESSAGE
|
|
|
59ad60 |
* job's priority if ours is higher. */
|
|
|
59ad60 |
if (pri > job->pri)
|
|
|
59ad60 |
job->pri = pri;
|
|
|
59ad60 |
|
|
|
59ad60 |
- QUEUE_UNLOCK (is);
|
|
|
59ad60 |
-
|
|
|
59ad60 |
/* Wait for the job to finish. */
|
|
|
59ad60 |
camel_imapx_job_wait (job);
|
|
|
59ad60 |
+ camel_imapx_job_unref (job);
|
|
|
59ad60 |
|
|
|
59ad60 |
/* Disregard errors here. If we failed to retreive the
|
|
|
59ad60 |
* message from cache (implying the job we were waiting
|
|
|
59ad60 |
@@ -7407,10 +7683,10 @@ imapx_server_get_message (CamelIMAPXServ
|
|
|
59ad60 |
ifolder->cache, "cur", uid, NULL);
|
|
|
59ad60 |
if (stream != NULL)
|
|
|
59ad60 |
return stream;
|
|
|
59ad60 |
-
|
|
|
59ad60 |
- QUEUE_LOCK (is);
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
+ QUEUE_LOCK (is);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
mi = camel_folder_summary_get (folder->summary, uid);
|
|
|
59ad60 |
if (!mi) {
|
|
|
59ad60 |
g_set_error (
|
|
|
59ad60 |
@@ -7700,15 +7976,17 @@ camel_imapx_server_refresh_info (CamelIM
|
|
|
59ad60 |
|
|
|
59ad60 |
full_name = camel_folder_get_full_name (folder);
|
|
|
59ad60 |
|
|
|
59ad60 |
- QUEUE_LOCK (is);
|
|
|
59ad60 |
-
|
|
|
59ad60 |
/* Both RefreshInfo and Fetch messages can't operate simultaneously */
|
|
|
59ad60 |
- if (imapx_is_job_in_queue (is, folder, IMAPX_JOB_REFRESH_INFO, NULL) ||
|
|
|
59ad60 |
- imapx_is_job_in_queue (is, folder, IMAPX_JOB_FETCH_MESSAGES, NULL)) {
|
|
|
59ad60 |
- QUEUE_UNLOCK (is);
|
|
|
59ad60 |
+ job = imapx_server_ref_job (is, folder, IMAPX_JOB_REFRESH_INFO, NULL);
|
|
|
59ad60 |
+ if (!job)
|
|
|
59ad60 |
+ job = imapx_server_ref_job (is, folder, IMAPX_JOB_FETCH_MESSAGES, NULL);
|
|
|
59ad60 |
+ if (job) {
|
|
|
59ad60 |
+ camel_imapx_job_unref (job);
|
|
|
59ad60 |
return TRUE;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
+ QUEUE_LOCK (is);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
data = g_slice_new0 (RefreshInfoData);
|
|
|
59ad60 |
data->changes = camel_folder_change_info_new ();
|
|
|
59ad60 |
|
|
|
59ad60 |
@@ -7963,13 +8241,11 @@ imapx_server_sync_changes (CamelIMAPXSer
|
|
|
59ad60 |
|
|
|
59ad60 |
/* TODO above code should go into changes_start */
|
|
|
59ad60 |
|
|
|
59ad60 |
- QUEUE_LOCK (is);
|
|
|
59ad60 |
-
|
|
|
59ad60 |
- if ((job = imapx_is_job_in_queue (is, folder, IMAPX_JOB_SYNC_CHANGES, NULL))) {
|
|
|
59ad60 |
+ if ((job = imapx_server_ref_job (is, folder, IMAPX_JOB_SYNC_CHANGES, NULL))) {
|
|
|
59ad60 |
if (pri > job->pri)
|
|
|
59ad60 |
job->pri = pri;
|
|
|
59ad60 |
|
|
|
59ad60 |
- QUEUE_UNLOCK (is);
|
|
|
59ad60 |
+ camel_imapx_job_unref (job);
|
|
|
59ad60 |
|
|
|
59ad60 |
imapx_sync_free_user (on_user);
|
|
|
59ad60 |
imapx_sync_free_user (off_user);
|
|
|
59ad60 |
@@ -7977,6 +8253,8 @@ imapx_server_sync_changes (CamelIMAPXSer
|
|
|
59ad60 |
return TRUE;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
+ QUEUE_LOCK (is);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
data = g_slice_new0 (SyncChangesData);
|
|
|
59ad60 |
data->folder = g_object_ref (folder);
|
|
|
59ad60 |
data->changed_uids = changed_uids; /* takes ownership */
|
|
|
59ad60 |
@@ -8036,13 +8314,15 @@ camel_imapx_server_expunge (CamelIMAPXSe
|
|
|
59ad60 |
gboolean success;
|
|
|
59ad60 |
|
|
|
59ad60 |
/* Do we really care to wait for this one to finish? */
|
|
|
59ad60 |
- QUEUE_LOCK (is);
|
|
|
59ad60 |
|
|
|
59ad60 |
- if (imapx_is_job_in_queue (is, folder, IMAPX_JOB_EXPUNGE, NULL)) {
|
|
|
59ad60 |
- QUEUE_UNLOCK (is);
|
|
|
59ad60 |
+ job = imapx_server_ref_job (is, folder, IMAPX_JOB_EXPUNGE, NULL);
|
|
|
59ad60 |
+ if (job) {
|
|
|
59ad60 |
+ camel_imapx_job_unref (job);
|
|
|
59ad60 |
return TRUE;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
+ QUEUE_LOCK (is);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
job = camel_imapx_job_new (cancellable);
|
|
|
59ad60 |
job->type = IMAPX_JOB_EXPUNGE;
|
|
|
59ad60 |
job->start = imapx_job_expunge_start;
|
|
|
59ad60 |
@@ -8270,15 +8550,17 @@ camel_imapx_server_fetch_messages (Camel
|
|
|
59ad60 |
firstuid = strtoull (uid, NULL, 10);
|
|
|
59ad60 |
g_free (uid);
|
|
|
59ad60 |
|
|
|
59ad60 |
- QUEUE_LOCK (is);
|
|
|
59ad60 |
-
|
|
|
59ad60 |
/* Both RefreshInfo and Fetch messages can't operate simultaneously */
|
|
|
59ad60 |
- if (imapx_is_job_in_queue (is, folder, IMAPX_JOB_REFRESH_INFO, NULL) ||
|
|
|
59ad60 |
- imapx_is_job_in_queue (is, folder, IMAPX_JOB_FETCH_MESSAGES, NULL)) {
|
|
|
59ad60 |
- QUEUE_UNLOCK (is);
|
|
|
59ad60 |
+ job = imapx_server_ref_job (is, folder, IMAPX_JOB_REFRESH_INFO, NULL);
|
|
|
59ad60 |
+ if (!job)
|
|
|
59ad60 |
+ job = imapx_server_ref_job (is, folder, IMAPX_JOB_FETCH_MESSAGES, NULL);
|
|
|
59ad60 |
+ if (job) {
|
|
|
59ad60 |
+ camel_imapx_job_unref (job);
|
|
|
59ad60 |
return TRUE;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
+ QUEUE_LOCK (is);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
data = g_slice_new0 (RefreshInfoData);
|
|
|
59ad60 |
data->changes = camel_folder_change_info_new ();
|
|
|
59ad60 |
data->fetch_msg_limit = limit;
|
|
|
59ad60 |
@@ -8450,55 +8732,54 @@ camel_imapx_server_uid_search (CamelIMAP
|
|
|
59ad60 |
return results;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
-IMAPXJobQueueInfo *
|
|
|
59ad60 |
-camel_imapx_server_get_job_queue_info (CamelIMAPXServer *is)
|
|
|
59ad60 |
+gboolean
|
|
|
59ad60 |
+camel_imapx_server_folder_name_in_jobs (CamelIMAPXServer *imapx_server,
|
|
|
59ad60 |
+ const gchar *folder_path)
|
|
|
59ad60 |
{
|
|
|
59ad60 |
- IMAPXJobQueueInfo *jinfo = g_new0 (IMAPXJobQueueInfo, 1);
|
|
|
59ad60 |
- CamelFolder *select_folder;
|
|
|
59ad60 |
- CamelIMAPXJob *job = NULL;
|
|
|
59ad60 |
- GList *head, *link;
|
|
|
59ad60 |
+ gboolean res;
|
|
|
59ad60 |
|
|
|
59ad60 |
- QUEUE_LOCK (is);
|
|
|
59ad60 |
+ g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (imapx_server), FALSE);
|
|
|
59ad60 |
+ g_return_val_if_fail (folder_path != NULL, FALSE);
|
|
|
59ad60 |
|
|
|
59ad60 |
- jinfo->queue_len = g_queue_get_length (&is->jobs);
|
|
|
59ad60 |
- jinfo->folders = g_hash_table_new_full (
|
|
|
59ad60 |
- (GHashFunc) g_str_hash,
|
|
|
59ad60 |
- (GEqualFunc) g_str_equal,
|
|
|
59ad60 |
- (GDestroyNotify) g_free,
|
|
|
59ad60 |
- (GDestroyNotify) NULL);
|
|
|
59ad60 |
+ g_mutex_lock (&imapx_server->priv->jobs_prop_lock);
|
|
|
59ad60 |
|
|
|
59ad60 |
- head = g_queue_peek_head_link (&is->jobs);
|
|
|
59ad60 |
+ res = GPOINTER_TO_INT (g_hash_table_lookup (imapx_server->priv->jobs_prop_folder_paths, folder_path)) > 0;
|
|
|
59ad60 |
|
|
|
59ad60 |
- for (link = head; link != NULL; link = g_list_next (link)) {
|
|
|
59ad60 |
- CamelFolder *folder;
|
|
|
59ad60 |
+ g_mutex_unlock (&imapx_server->priv->jobs_prop_lock);
|
|
|
59ad60 |
|
|
|
59ad60 |
- job = (CamelIMAPXJob *) link->data;
|
|
|
59ad60 |
- folder = camel_imapx_job_ref_folder (job);
|
|
|
59ad60 |
+ return res;
|
|
|
59ad60 |
+}
|
|
|
59ad60 |
|
|
|
59ad60 |
- if (folder != NULL) {
|
|
|
59ad60 |
- gchar *folder_name;
|
|
|
59ad60 |
+gboolean
|
|
|
59ad60 |
+camel_imapx_server_has_expensive_command (CamelIMAPXServer *imapx_server)
|
|
|
59ad60 |
+{
|
|
|
59ad60 |
+ gboolean res;
|
|
|
59ad60 |
|
|
|
59ad60 |
- folder_name = camel_folder_dup_full_name (folder);
|
|
|
59ad60 |
- g_hash_table_add (jinfo->folders, folder_name);
|
|
|
59ad60 |
+ g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (imapx_server), FALSE);
|
|
|
59ad60 |
|
|
|
59ad60 |
- g_object_unref (folder);
|
|
|
59ad60 |
- }
|
|
|
59ad60 |
- }
|
|
|
59ad60 |
+ g_mutex_lock (&imapx_server->priv->jobs_prop_lock);
|
|
|
59ad60 |
|
|
|
59ad60 |
- select_folder = g_weak_ref_get (&is->select_folder);
|
|
|
59ad60 |
+ res = imapx_server->priv->jobs_prop_expensive_command_count > 0;
|
|
|
59ad60 |
|
|
|
59ad60 |
- if (select_folder != NULL) {
|
|
|
59ad60 |
- gchar *folder_name;
|
|
|
59ad60 |
+ g_mutex_unlock (&imapx_server->priv->jobs_prop_lock);
|
|
|
59ad60 |
|
|
|
59ad60 |
- folder_name = camel_folder_dup_full_name (select_folder);
|
|
|
59ad60 |
- g_hash_table_add (jinfo->folders, folder_name);
|
|
|
59ad60 |
+ return res;
|
|
|
59ad60 |
+}
|
|
|
59ad60 |
|
|
|
59ad60 |
- g_object_unref (select_folder);
|
|
|
59ad60 |
- }
|
|
|
59ad60 |
+gint
|
|
|
59ad60 |
+camel_imapx_server_get_command_count (CamelIMAPXServer *imapx_server)
|
|
|
59ad60 |
+{
|
|
|
59ad60 |
+ guint32 res;
|
|
|
59ad60 |
|
|
|
59ad60 |
- QUEUE_UNLOCK (is);
|
|
|
59ad60 |
+ g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (imapx_server), -1);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_mutex_lock (&imapx_server->priv->jobs_prop_lock);
|
|
|
59ad60 |
|
|
|
59ad60 |
- return jinfo;
|
|
|
59ad60 |
+ res = imapx_server->priv->jobs_prop_command_count;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_mutex_unlock (&imapx_server->priv->jobs_prop_lock);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ return res;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
/**
|
|
|
59ad60 |
@@ -8575,3 +8856,108 @@ camel_imapx_server_command_run (CamelIMA
|
|
|
59ad60 |
|
|
|
59ad60 |
return ok;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+/**
|
|
|
59ad60 |
+ * camel_imapx_server_is_job_in_queue:
|
|
|
59ad60 |
+ * @imapx_server: a #CamelIMAPXServer instance
|
|
|
59ad60 |
+ * @folder: a folder to search job for
|
|
|
59ad60 |
+ * @job_type: a job type specifier to search for
|
|
|
59ad60 |
+ * @uid: optional message UID for which the job might be searched
|
|
|
59ad60 |
+ *
|
|
|
59ad60 |
+ * Searches queue of jobs for the particular job. The returned job
|
|
|
59ad60 |
+ * is referenced for thread safety, unref it with camel_imapx_job_unref().
|
|
|
59ad60 |
+ *
|
|
|
59ad60 |
+ * Returns: %NULL, if such job could not be found, or a referenced job.
|
|
|
59ad60 |
+ **/
|
|
|
59ad60 |
+CamelIMAPXJob *
|
|
|
59ad60 |
+camel_imapx_server_ref_job (CamelIMAPXServer *imapx_server,
|
|
|
59ad60 |
+ CamelFolder *folder,
|
|
|
59ad60 |
+ guint32 job_type,
|
|
|
59ad60 |
+ const gchar *uid)
|
|
|
59ad60 |
+{
|
|
|
59ad60 |
+ GList *head, *link;
|
|
|
59ad60 |
+ CamelIMAPXJob *job = NULL;
|
|
|
59ad60 |
+ gboolean found = FALSE;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (imapx_server), NULL);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ QUEUE_LOCK (imapx_server);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ head = g_queue_peek_head_link (&imapx_server->jobs);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ for (link = head; link != NULL; link = g_list_next (link)) {
|
|
|
59ad60 |
+ job = (CamelIMAPXJob *) link->data;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (!job || !(job->type & job_type))
|
|
|
59ad60 |
+ continue;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (camel_imapx_job_matches (job, folder, uid)) {
|
|
|
59ad60 |
+ found = TRUE;
|
|
|
59ad60 |
+ camel_imapx_job_ref (job);
|
|
|
59ad60 |
+ break;
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ QUEUE_UNLOCK (imapx_server);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ return found ? job : NULL;
|
|
|
59ad60 |
+}
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+/**
|
|
|
59ad60 |
+ * camel_imapx_server_shutdown:
|
|
|
59ad60 |
+ * @is: a #CamelIMAPXServer
|
|
|
59ad60 |
+ * @error: a #GError with which cancel any pending jobs
|
|
|
59ad60 |
+ *
|
|
|
59ad60 |
+ * Signals the server to shut down command processing. A #CamelIMAPXStore
|
|
|
59ad60 |
+ * should call this immediately before unreferencing its server instance.
|
|
|
59ad60 |
+ * Note, the server instance may linger a short time after this function
|
|
|
59ad60 |
+ * returns as its own worker threads finish.
|
|
|
59ad60 |
+ *
|
|
|
59ad60 |
+ * Since: 3.12
|
|
|
59ad60 |
+ **/
|
|
|
59ad60 |
+void
|
|
|
59ad60 |
+camel_imapx_server_shutdown (CamelIMAPXServer *is,
|
|
|
59ad60 |
+ const GError *error)
|
|
|
59ad60 |
+{
|
|
|
59ad60 |
+ GCancellable *cancellable;
|
|
|
59ad60 |
+ GError *shutdown_error_copy = NULL;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_return_if_fail (CAMEL_IS_IMAPX_SERVER (is));
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ QUEUE_LOCK (is);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ is->parser_quit = TRUE;
|
|
|
59ad60 |
+ is->state = IMAPX_SHUTDOWN;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (is->cancellable)
|
|
|
59ad60 |
+ cancellable = g_object_ref (is->cancellable);
|
|
|
59ad60 |
+ else
|
|
|
59ad60 |
+ cancellable = NULL;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ QUEUE_UNLOCK (is);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (!error) {
|
|
|
59ad60 |
+ shutdown_error_copy = imapx_server_dup_shutdown_error (is);
|
|
|
59ad60 |
+ error = shutdown_error_copy;
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (error) {
|
|
|
59ad60 |
+ cancel_all_jobs (is, error);
|
|
|
59ad60 |
+ } else {
|
|
|
59ad60 |
+ GError *local_error = NULL;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_set_error (
|
|
|
59ad60 |
+ &local_error, CAMEL_SERVICE_ERROR,
|
|
|
59ad60 |
+ CAMEL_SERVICE_ERROR_UNAVAILABLE,
|
|
|
59ad60 |
+ "Shutting down");
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ cancel_all_jobs (is, local_error);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_clear_error (&local_error);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (cancellable)
|
|
|
59ad60 |
+ g_cancellable_cancel (cancellable);
|
|
|
59ad60 |
+ g_clear_object (&cancellable);
|
|
|
59ad60 |
+ g_clear_error (&shutdown_error_copy);
|
|
|
59ad60 |
+}
|
|
|
59ad60 |
diff -up evolution-data-server-3.8.5/camel/camel-imapx-server.h.imapx-conn-manager-ext evolution-data-server-3.8.5/camel/camel-imapx-server.h
|
|
|
59ad60 |
--- evolution-data-server-3.8.5/camel/camel-imapx-server.h.imapx-conn-manager-ext 2013-07-23 13:57:54.000000000 +0200
|
|
|
59ad60 |
+++ evolution-data-server-3.8.5/camel/camel-imapx-server.h 2014-05-13 14:17:43.118983665 +0200
|
|
|
59ad60 |
@@ -53,18 +53,27 @@
|
|
|
59ad60 |
#define IMAPX_MODE_READ (1 << 0)
|
|
|
59ad60 |
#define IMAPX_MODE_WRITE (1 << 1)
|
|
|
59ad60 |
|
|
|
59ad60 |
+#define CAMEL_IMAPX_SERVER_ERROR (camel_imapx_server_error_quark ())
|
|
|
59ad60 |
+
|
|
|
59ad60 |
G_BEGIN_DECLS
|
|
|
59ad60 |
|
|
|
59ad60 |
+typedef enum {
|
|
|
59ad60 |
+ CAMEL_IMAPX_SERVER_ERROR_CONCURRENT_CONNECT_FAILED,
|
|
|
59ad60 |
+ CAMEL_IMAPX_SERVER_ERROR_TRY_RECONNECT
|
|
|
59ad60 |
+} CamelIMAPXServerError;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+GQuark camel_imapx_server_error_quark (void) G_GNUC_CONST;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
/* Avoid a circular reference. */
|
|
|
59ad60 |
struct _CamelIMAPXStore;
|
|
|
59ad60 |
struct _CamelIMAPXSettings;
|
|
|
59ad60 |
+struct _CamelIMAPXJob;
|
|
|
59ad60 |
|
|
|
59ad60 |
typedef struct _CamelIMAPXServer CamelIMAPXServer;
|
|
|
59ad60 |
typedef struct _CamelIMAPXServerClass CamelIMAPXServerClass;
|
|
|
59ad60 |
typedef struct _CamelIMAPXServerPrivate CamelIMAPXServerPrivate;
|
|
|
59ad60 |
|
|
|
59ad60 |
typedef struct _CamelIMAPXIdle CamelIMAPXIdle;
|
|
|
59ad60 |
-struct _IMAPXJobQueueInfo;
|
|
|
59ad60 |
|
|
|
59ad60 |
/* untagged response handling */
|
|
|
59ad60 |
typedef gboolean
|
|
|
59ad60 |
@@ -167,7 +176,8 @@ struct _CamelIMAPXServerClass {
|
|
|
59ad60 |
/* Signals */
|
|
|
59ad60 |
void (*select_changed) (CamelIMAPXServer *is,
|
|
|
59ad60 |
const gchar *selected_folder);
|
|
|
59ad60 |
- void (*shutdown) (CamelIMAPXServer *is);
|
|
|
59ad60 |
+ void (*shutdown) (CamelIMAPXServer *is,
|
|
|
59ad60 |
+ const GError *error);
|
|
|
59ad60 |
|
|
|
59ad60 |
gchar tagprefix;
|
|
|
59ad60 |
};
|
|
|
59ad60 |
@@ -184,6 +194,9 @@ CamelIMAPXStream *
|
|
|
59ad60 |
gboolean camel_imapx_server_connect (CamelIMAPXServer *is,
|
|
|
59ad60 |
GCancellable *cancellable,
|
|
|
59ad60 |
GError **error);
|
|
|
59ad60 |
+gboolean camel_imapx_server_disconnect (CamelIMAPXServer *is);
|
|
|
59ad60 |
+void camel_imapx_server_shutdown (CamelIMAPXServer *is,
|
|
|
59ad60 |
+ const GError *error);
|
|
|
59ad60 |
gboolean imapx_connect_to_server (CamelIMAPXServer *is,
|
|
|
59ad60 |
GCancellable *cancellable,
|
|
|
59ad60 |
GError **error);
|
|
|
59ad60 |
@@ -278,9 +291,13 @@ GPtrArray * camel_imapx_server_uid_searc
|
|
|
59ad60 |
const gchar *criteria,
|
|
|
59ad60 |
GCancellable *cancellable,
|
|
|
59ad60 |
GError **error);
|
|
|
59ad60 |
-struct _IMAPXJobQueueInfo *
|
|
|
59ad60 |
- camel_imapx_server_get_job_queue_info
|
|
|
59ad60 |
- (CamelIMAPXServer *is);
|
|
|
59ad60 |
+gboolean camel_imapx_server_folder_name_in_jobs
|
|
|
59ad60 |
+ (CamelIMAPXServer *imapx_server,
|
|
|
59ad60 |
+ const gchar *folder_path);
|
|
|
59ad60 |
+gboolean camel_imapx_server_has_expensive_command
|
|
|
59ad60 |
+ (CamelIMAPXServer *imapx_server);
|
|
|
59ad60 |
+gint camel_imapx_server_get_command_count
|
|
|
59ad60 |
+ (CamelIMAPXServer *imapx_server);
|
|
|
59ad60 |
const CamelIMAPXUntaggedRespHandlerDesc *
|
|
|
59ad60 |
camel_imapx_server_register_untagged_handler
|
|
|
59ad60 |
(CamelIMAPXServer *is,
|
|
|
59ad60 |
@@ -290,6 +307,11 @@ gboolean camel_imapx_server_command_run
|
|
|
59ad60 |
CamelIMAPXCommand *ic,
|
|
|
59ad60 |
GCancellable *cancellable,
|
|
|
59ad60 |
GError **error);
|
|
|
59ad60 |
+struct _CamelIMAPXJob *
|
|
|
59ad60 |
+ camel_imapx_server_ref_job (CamelIMAPXServer *imapx_server,
|
|
|
59ad60 |
+ CamelFolder *folder,
|
|
|
59ad60 |
+ guint32 job_type,
|
|
|
59ad60 |
+ const gchar *uid);
|
|
|
59ad60 |
|
|
|
59ad60 |
G_END_DECLS
|
|
|
59ad60 |
|
|
|
59ad60 |
diff -up evolution-data-server-3.8.5/camel/camel-imapx-settings.c.imapx-conn-manager-ext evolution-data-server-3.8.5/camel/camel-imapx-settings.c
|
|
|
59ad60 |
--- evolution-data-server-3.8.5/camel/camel-imapx-settings.c.imapx-conn-manager-ext 2013-07-23 13:57:50.000000000 +0200
|
|
|
59ad60 |
+++ evolution-data-server-3.8.5/camel/camel-imapx-settings.c 2014-05-13 14:17:43.118983665 +0200
|
|
|
59ad60 |
@@ -516,7 +516,7 @@ camel_imapx_settings_class_init (CamelIM
|
|
|
59ad60 |
"Number of concurrent IMAP connections to use",
|
|
|
59ad60 |
MIN_CONCURRENT_CONNECTIONS,
|
|
|
59ad60 |
MAX_CONCURRENT_CONNECTIONS,
|
|
|
59ad60 |
- 5,
|
|
|
59ad60 |
+ 3,
|
|
|
59ad60 |
G_PARAM_READWRITE |
|
|
|
59ad60 |
G_PARAM_CONSTRUCT |
|
|
|
59ad60 |
G_PARAM_STATIC_STRINGS));
|
|
|
59ad60 |
diff -up evolution-data-server-3.8.5/camel/camel-imapx-store.c.imapx-conn-manager-ext evolution-data-server-3.8.5/camel/camel-imapx-store.c
|
|
|
59ad60 |
--- evolution-data-server-3.8.5/camel/camel-imapx-store.c.imapx-conn-manager-ext 2014-05-13 14:17:43.114983665 +0200
|
|
|
59ad60 |
+++ evolution-data-server-3.8.5/camel/camel-imapx-store.c 2014-05-13 14:17:43.119983665 +0200
|
|
|
59ad60 |
@@ -40,6 +40,7 @@
|
|
|
59ad60 |
#include <glib/gi18n-lib.h>
|
|
|
59ad60 |
|
|
|
59ad60 |
#include "camel-imapx-folder.h"
|
|
|
59ad60 |
+#include "camel-imapx-job.h"
|
|
|
59ad60 |
#include "camel-imapx-server.h"
|
|
|
59ad60 |
#include "camel-imapx-settings.h"
|
|
|
59ad60 |
#include "camel-imapx-store.h"
|
|
|
59ad60 |
@@ -59,6 +60,7 @@
|
|
|
59ad60 |
struct _CamelIMAPXStorePrivate {
|
|
|
59ad60 |
GHashTable *quota_info;
|
|
|
59ad60 |
GMutex quota_info_lock;
|
|
|
59ad60 |
+ gboolean is_concurrent_connection;
|
|
|
59ad60 |
};
|
|
|
59ad60 |
|
|
|
59ad60 |
enum {
|
|
|
59ad60 |
@@ -260,11 +262,12 @@ imapx_get_name (CamelService *service,
|
|
|
59ad60 |
CamelIMAPXServer *
|
|
|
59ad60 |
camel_imapx_store_get_server (CamelIMAPXStore *istore,
|
|
|
59ad60 |
const gchar *folder_name,
|
|
|
59ad60 |
+ gboolean for_expensive_job,
|
|
|
59ad60 |
GCancellable *cancellable,
|
|
|
59ad60 |
GError **error)
|
|
|
59ad60 |
{
|
|
|
59ad60 |
return camel_imapx_conn_manager_get_connection (
|
|
|
59ad60 |
- istore->con_man, folder_name, cancellable, error);
|
|
|
59ad60 |
+ istore->con_man, folder_name, for_expensive_job, cancellable, error);
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
void
|
|
|
59ad60 |
@@ -286,7 +289,7 @@ imapx_connect_sync (CamelService *servic
|
|
|
59ad60 |
CamelIMAPXStore *istore = (CamelIMAPXStore *) service;
|
|
|
59ad60 |
CamelIMAPXServer *server;
|
|
|
59ad60 |
|
|
|
59ad60 |
- server = camel_imapx_store_get_server (istore, NULL, cancellable, error);
|
|
|
59ad60 |
+ server = camel_imapx_store_get_server (istore, NULL, FALSE, cancellable, error);
|
|
|
59ad60 |
if (server) {
|
|
|
59ad60 |
g_object_unref (server);
|
|
|
59ad60 |
return TRUE;
|
|
|
59ad60 |
@@ -309,7 +312,7 @@ imapx_disconnect_sync (CamelService *ser
|
|
|
59ad60 |
res = service_class->disconnect_sync (service, clean, cancellable, error);
|
|
|
59ad60 |
|
|
|
59ad60 |
if (istore->con_man != NULL)
|
|
|
59ad60 |
- camel_imapx_conn_manager_close_connections (istore->con_man);
|
|
|
59ad60 |
+ camel_imapx_conn_manager_close_connections (istore->con_man, NULL);
|
|
|
59ad60 |
|
|
|
59ad60 |
return res;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
@@ -333,7 +336,7 @@ imapx_authenticate_sync (CamelService *s
|
|
|
59ad60 |
|
|
|
59ad60 |
g_return_val_if_fail (
|
|
|
59ad60 |
CAMEL_IS_IMAPX_SERVER (server),
|
|
|
59ad60 |
- CAMEL_AUTHENTICATION_REJECTED);
|
|
|
59ad60 |
+ CAMEL_AUTHENTICATION_ERROR);
|
|
|
59ad60 |
|
|
|
59ad60 |
return camel_imapx_server_authenticate (
|
|
|
59ad60 |
server, mechanism, cancellable, error);
|
|
|
59ad60 |
@@ -657,22 +660,35 @@ imapx_subscribe_folder (CamelStore *stor
|
|
|
59ad60 |
{
|
|
|
59ad60 |
CamelIMAPXStore *istore = (CamelIMAPXStore *) store;
|
|
|
59ad60 |
CamelIMAPXServer *server;
|
|
|
59ad60 |
+ GError *local_error = NULL;
|
|
|
59ad60 |
gboolean success;
|
|
|
59ad60 |
|
|
|
59ad60 |
if (!camel_offline_store_get_online (CAMEL_OFFLINE_STORE (store)))
|
|
|
59ad60 |
return TRUE;
|
|
|
59ad60 |
|
|
|
59ad60 |
- server = camel_imapx_store_get_server (istore, NULL, cancellable, error);
|
|
|
59ad60 |
+ server = camel_imapx_store_get_server (istore, NULL, FALSE, cancellable, error);
|
|
|
59ad60 |
if (!server)
|
|
|
59ad60 |
return FALSE;
|
|
|
59ad60 |
|
|
|
59ad60 |
if (folder_name && *folder_name == '/')
|
|
|
59ad60 |
folder_name++;
|
|
|
59ad60 |
|
|
|
59ad60 |
- success = camel_imapx_server_manage_subscription (
|
|
|
59ad60 |
- server, folder_name, TRUE, cancellable, error);
|
|
|
59ad60 |
+ success = camel_imapx_server_manage_subscription (server, folder_name, TRUE, cancellable, &local_error);
|
|
|
59ad60 |
g_object_unref (server);
|
|
|
59ad60 |
|
|
|
59ad60 |
+ while (!success && g_error_matches (local_error, CAMEL_IMAPX_SERVER_ERROR, CAMEL_IMAPX_SERVER_ERROR_TRY_RECONNECT)) {
|
|
|
59ad60 |
+ g_clear_error (&local_error);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ server = camel_imapx_store_get_server (istore, NULL, FALSE, cancellable, &local_error);
|
|
|
59ad60 |
+ if (server) {
|
|
|
59ad60 |
+ success = camel_imapx_server_manage_subscription (server, folder_name, TRUE, cancellable, &local_error);
|
|
|
59ad60 |
+ g_object_unref (server);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (local_error)
|
|
|
59ad60 |
+ g_propagate_error (error, local_error);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
if (success)
|
|
|
59ad60 |
imapx_mark_folder_subscribed (istore, folder_name, emit_signal);
|
|
|
59ad60 |
|
|
|
59ad60 |
@@ -688,22 +704,35 @@ imapx_unsubscribe_folder (CamelStore *st
|
|
|
59ad60 |
{
|
|
|
59ad60 |
CamelIMAPXStore *istore = (CamelIMAPXStore *) store;
|
|
|
59ad60 |
CamelIMAPXServer *server;
|
|
|
59ad60 |
+ GError *local_error = NULL;
|
|
|
59ad60 |
gboolean success;
|
|
|
59ad60 |
|
|
|
59ad60 |
if (!camel_offline_store_get_online (CAMEL_OFFLINE_STORE (store)))
|
|
|
59ad60 |
return TRUE;
|
|
|
59ad60 |
|
|
|
59ad60 |
- server = camel_imapx_store_get_server (istore, NULL, cancellable, error);
|
|
|
59ad60 |
+ server = camel_imapx_store_get_server (istore, NULL, FALSE, cancellable, error);
|
|
|
59ad60 |
if (!server)
|
|
|
59ad60 |
return FALSE;
|
|
|
59ad60 |
|
|
|
59ad60 |
if (folder_name && *folder_name == '/')
|
|
|
59ad60 |
folder_name++;
|
|
|
59ad60 |
|
|
|
59ad60 |
- success = camel_imapx_server_manage_subscription (
|
|
|
59ad60 |
- server, folder_name, FALSE, cancellable, error);
|
|
|
59ad60 |
+ success = camel_imapx_server_manage_subscription (server, folder_name, FALSE, cancellable, &local_error);
|
|
|
59ad60 |
g_object_unref (server);
|
|
|
59ad60 |
|
|
|
59ad60 |
+ while (!success && g_error_matches (local_error, CAMEL_IMAPX_SERVER_ERROR, CAMEL_IMAPX_SERVER_ERROR_TRY_RECONNECT)) {
|
|
|
59ad60 |
+ g_clear_error (&local_error);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ server = camel_imapx_store_get_server (istore, NULL, FALSE, cancellable, &local_error);
|
|
|
59ad60 |
+ if (server) {
|
|
|
59ad60 |
+ success = camel_imapx_server_manage_subscription (server, folder_name, FALSE, cancellable, &local_error);
|
|
|
59ad60 |
+ g_object_unref (server);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (local_error)
|
|
|
59ad60 |
+ g_propagate_error (error, local_error);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
if (success)
|
|
|
59ad60 |
imapx_unmark_folder_subscribed (istore, folder_name, emit_signal);
|
|
|
59ad60 |
|
|
|
59ad60 |
@@ -1012,9 +1041,23 @@ fetch_folders_for_pattern (CamelIMAPXSto
|
|
|
59ad60 |
GPtrArray *folders;
|
|
|
59ad60 |
GError *local_error = NULL;
|
|
|
59ad60 |
|
|
|
59ad60 |
+ g_object_ref (server);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
folders = camel_imapx_server_list (
|
|
|
59ad60 |
server, pattern, flags, ext, cancellable, &local_error);
|
|
|
59ad60 |
- if (folders == NULL || local_error) {
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ while (!folders && g_error_matches (local_error, CAMEL_IMAPX_SERVER_ERROR, CAMEL_IMAPX_SERVER_ERROR_TRY_RECONNECT)) {
|
|
|
59ad60 |
+ g_clear_error (&local_error);
|
|
|
59ad60 |
+ g_clear_object (&server);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ server = camel_imapx_store_get_server (istore, NULL, FALSE, cancellable, &local_error);
|
|
|
59ad60 |
+ if (server)
|
|
|
59ad60 |
+ folders = camel_imapx_server_list (server, pattern, flags, ext, cancellable, &local_error);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (folders == NULL || local_error || !server) {
|
|
|
59ad60 |
+ g_clear_object (&server);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
if (local_error)
|
|
|
59ad60 |
g_propagate_error (error, local_error);
|
|
|
59ad60 |
return FALSE;
|
|
|
59ad60 |
@@ -1022,6 +1065,8 @@ fetch_folders_for_pattern (CamelIMAPXSto
|
|
|
59ad60 |
|
|
|
59ad60 |
add_folders_to_summary (istore, server, folders, table, (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED));
|
|
|
59ad60 |
|
|
|
59ad60 |
+ g_clear_object (&server);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
g_ptr_array_foreach (folders, free_list, folders);
|
|
|
59ad60 |
g_ptr_array_free (folders, TRUE);
|
|
|
59ad60 |
|
|
|
59ad60 |
@@ -1057,7 +1102,7 @@ fetch_folders_for_namespaces (CamelIMAPX
|
|
|
59ad60 |
GHashTable *folders = NULL;
|
|
|
59ad60 |
GList *namespaces = NULL, *l;
|
|
|
59ad60 |
|
|
|
59ad60 |
- server = camel_imapx_store_get_server (istore, NULL, cancellable, error);
|
|
|
59ad60 |
+ server = camel_imapx_store_get_server (istore, NULL, FALSE, cancellable, error);
|
|
|
59ad60 |
if (!server)
|
|
|
59ad60 |
return NULL;
|
|
|
59ad60 |
|
|
|
59ad60 |
@@ -1581,6 +1626,7 @@ imapx_store_create_folder_sync (CamelSto
|
|
|
59ad60 |
gchar *real_name, *full_name, *parent_real;
|
|
|
59ad60 |
CamelFolderInfo *fi = NULL;
|
|
|
59ad60 |
gchar dir_sep = 0;
|
|
|
59ad60 |
+ GError *local_error = NULL;
|
|
|
59ad60 |
gboolean success;
|
|
|
59ad60 |
|
|
|
59ad60 |
if (!camel_offline_store_get_online (CAMEL_OFFLINE_STORE (store))) {
|
|
|
59ad60 |
@@ -1591,7 +1637,7 @@ imapx_store_create_folder_sync (CamelSto
|
|
|
59ad60 |
return NULL;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
- server = camel_imapx_store_get_server (istore, NULL, cancellable, error);
|
|
|
59ad60 |
+ server = camel_imapx_store_get_server (istore, NULL, FALSE, cancellable, error);
|
|
|
59ad60 |
if (!server)
|
|
|
59ad60 |
return NULL;
|
|
|
59ad60 |
|
|
|
59ad60 |
@@ -1642,10 +1688,22 @@ imapx_store_create_folder_sync (CamelSto
|
|
|
59ad60 |
full_name = imapx_concat (istore, parent_real, real_name);
|
|
|
59ad60 |
g_free (real_name);
|
|
|
59ad60 |
|
|
|
59ad60 |
- success = camel_imapx_server_create_folder (
|
|
|
59ad60 |
- server, full_name, cancellable, error);
|
|
|
59ad60 |
+ success = camel_imapx_server_create_folder (server, full_name, cancellable, &local_error);
|
|
|
59ad60 |
g_object_unref (server);
|
|
|
59ad60 |
|
|
|
59ad60 |
+ while (!success && g_error_matches (local_error, CAMEL_IMAPX_SERVER_ERROR, CAMEL_IMAPX_SERVER_ERROR_TRY_RECONNECT)) {
|
|
|
59ad60 |
+ g_clear_error (&local_error);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ server = camel_imapx_store_get_server (istore, NULL, FALSE, cancellable, &local_error);
|
|
|
59ad60 |
+ if (server) {
|
|
|
59ad60 |
+ success = camel_imapx_server_create_folder (server, full_name, cancellable, &local_error);
|
|
|
59ad60 |
+ g_object_unref (server);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (local_error)
|
|
|
59ad60 |
+ g_propagate_error (error, local_error);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
if (success) {
|
|
|
59ad60 |
CamelIMAPXStoreInfo *si;
|
|
|
59ad60 |
|
|
|
59ad60 |
@@ -1670,6 +1728,7 @@ imapx_store_delete_folder_sync (CamelSto
|
|
|
59ad60 |
{
|
|
|
59ad60 |
CamelIMAPXStore *istore = (CamelIMAPXStore *) store;
|
|
|
59ad60 |
CamelIMAPXServer *server;
|
|
|
59ad60 |
+ GError *local_error = NULL;
|
|
|
59ad60 |
gboolean success;
|
|
|
59ad60 |
|
|
|
59ad60 |
if (!camel_offline_store_get_online (CAMEL_OFFLINE_STORE (store))) {
|
|
|
59ad60 |
@@ -1681,14 +1740,28 @@ imapx_store_delete_folder_sync (CamelSto
|
|
|
59ad60 |
}
|
|
|
59ad60 |
/* Use INBOX connection as the implementation would try to select inbox to ensure
|
|
|
59ad60 |
* we are not selected on the folder being deleted */
|
|
|
59ad60 |
- server = camel_imapx_store_get_server (istore, "INBOX", cancellable, error);
|
|
|
59ad60 |
+ server = camel_imapx_store_get_server (istore, "INBOX", FALSE, cancellable, error);
|
|
|
59ad60 |
if (!server)
|
|
|
59ad60 |
return FALSE;
|
|
|
59ad60 |
|
|
|
59ad60 |
- success = camel_imapx_server_delete_folder (
|
|
|
59ad60 |
- server, folder_name, cancellable, error);
|
|
|
59ad60 |
+ success = camel_imapx_server_delete_folder (server, folder_name, cancellable, &local_error);
|
|
|
59ad60 |
+ camel_imapx_store_op_done (istore, server, "INBOX");
|
|
|
59ad60 |
g_object_unref (server);
|
|
|
59ad60 |
|
|
|
59ad60 |
+ while (!success && g_error_matches (local_error, CAMEL_IMAPX_SERVER_ERROR, CAMEL_IMAPX_SERVER_ERROR_TRY_RECONNECT)) {
|
|
|
59ad60 |
+ g_clear_error (&local_error);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ server = camel_imapx_store_get_server (istore, "INBOX", FALSE, cancellable, &local_error);
|
|
|
59ad60 |
+ if (server) {
|
|
|
59ad60 |
+ success = camel_imapx_server_delete_folder (server, folder_name, cancellable, &local_error);
|
|
|
59ad60 |
+ camel_imapx_store_op_done (istore, server, "INBOX");
|
|
|
59ad60 |
+ g_object_unref (server);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (local_error)
|
|
|
59ad60 |
+ g_propagate_error (error, local_error);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
if (success)
|
|
|
59ad60 |
imapx_delete_folder_from_cache (istore, folder_name);
|
|
|
59ad60 |
|
|
|
59ad60 |
@@ -1734,11 +1807,28 @@ imapx_store_rename_folder_sync (CamelSto
|
|
|
59ad60 |
|
|
|
59ad60 |
/* Use INBOX connection as the implementation would try to select inbox to ensure
|
|
|
59ad60 |
* we are not selected on the folder being renamed */
|
|
|
59ad60 |
- server = camel_imapx_store_get_server (istore, "INBOX", cancellable, error);
|
|
|
59ad60 |
+ server = camel_imapx_store_get_server (istore, "INBOX", FALSE, cancellable, error);
|
|
|
59ad60 |
if (server) {
|
|
|
59ad60 |
- success = camel_imapx_server_rename_folder (
|
|
|
59ad60 |
- server, old, new, cancellable, error);
|
|
|
59ad60 |
+ GError *local_error = NULL;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ success = camel_imapx_server_rename_folder (server, old, new, cancellable, &local_error);
|
|
|
59ad60 |
+ camel_imapx_store_op_done (istore, server, "INBOX");
|
|
|
59ad60 |
g_object_unref (server);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ while (!success && g_error_matches (local_error, CAMEL_IMAPX_SERVER_ERROR, CAMEL_IMAPX_SERVER_ERROR_TRY_RECONNECT)) {
|
|
|
59ad60 |
+ g_clear_error (&local_error);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ server = camel_imapx_store_get_server (istore, "INBOX", FALSE, cancellable, &local_error);
|
|
|
59ad60 |
+ if (server) {
|
|
|
59ad60 |
+ success = camel_imapx_server_rename_folder (server, old, new, cancellable, &local_error);
|
|
|
59ad60 |
+ camel_imapx_store_op_done (istore, server, "INBOX");
|
|
|
59ad60 |
+ g_object_unref (server);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (local_error)
|
|
|
59ad60 |
+ g_propagate_error (error, local_error);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
if (!success) {
|
|
|
59ad60 |
@@ -1787,9 +1877,18 @@ imapx_store_noop_sync (CamelStore *store
|
|
|
59ad60 |
|
|
|
59ad60 |
for (link = list; link != NULL; link = g_list_next (link)) {
|
|
|
59ad60 |
CamelIMAPXServer *server = CAMEL_IMAPX_SERVER (link->data);
|
|
|
59ad60 |
+ GError *local_error = NULL;
|
|
|
59ad60 |
|
|
|
59ad60 |
/* we just return last noops value, technically not correct though */
|
|
|
59ad60 |
- success = camel_imapx_server_noop (server, NULL, cancellable, error);
|
|
|
59ad60 |
+ success = camel_imapx_server_noop (server, NULL, cancellable, &local_error);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ if (g_error_matches (local_error, CAMEL_IMAPX_SERVER_ERROR, CAMEL_IMAPX_SERVER_ERROR_TRY_RECONNECT)) {
|
|
|
59ad60 |
+ g_clear_error (&local_error);
|
|
|
59ad60 |
+ break;
|
|
|
59ad60 |
+ } else if (local_error) {
|
|
|
59ad60 |
+ g_propagate_error (error, local_error);
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
if (!success)
|
|
|
59ad60 |
break;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
@@ -2081,3 +2180,49 @@ camel_imapx_store_set_quota_info (CamelI
|
|
|
59ad60 |
g_mutex_unlock (&store->priv->quota_info_lock);
|
|
|
59ad60 |
}
|
|
|
59ad60 |
|
|
|
59ad60 |
+void
|
|
|
59ad60 |
+camel_imapx_store_set_authenticating_concurrent_connection (CamelIMAPXStore *store,
|
|
|
59ad60 |
+ gboolean is_concurrent_connection)
|
|
|
59ad60 |
+{
|
|
|
59ad60 |
+ g_return_if_fail (CAMEL_IS_IMAPX_STORE (store));
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ store->priv->is_concurrent_connection = is_concurrent_connection;
|
|
|
59ad60 |
+}
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+gboolean
|
|
|
59ad60 |
+camel_imapx_store_get_authenticating_concurrent_connection (CamelIMAPXStore *store)
|
|
|
59ad60 |
+{
|
|
|
59ad60 |
+ g_return_val_if_fail (CAMEL_IS_IMAPX_STORE (store), FALSE);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ return store->priv->is_concurrent_connection;
|
|
|
59ad60 |
+}
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+/* Tries to find matching job among all active connections.
|
|
|
59ad60 |
+ See camel_imapx_server_ref_job() for more information on parameters
|
|
|
59ad60 |
+ and return values.
|
|
|
59ad60 |
+*/
|
|
|
59ad60 |
+CamelIMAPXJob *
|
|
|
59ad60 |
+camel_imapx_store_ref_job (CamelIMAPXStore *imapx_store,
|
|
|
59ad60 |
+ CamelFolder *folder,
|
|
|
59ad60 |
+ guint32 job_type,
|
|
|
59ad60 |
+ const gchar *uid)
|
|
|
59ad60 |
+{
|
|
|
59ad60 |
+ GList *servers, *siter;
|
|
|
59ad60 |
+ CamelIMAPXJob *job = NULL;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_return_val_if_fail (CAMEL_IS_IMAPX_STORE (imapx_store), NULL);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ servers = camel_imapx_conn_manager_get_connections (imapx_store->con_man);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ for (siter = servers; siter; siter = g_list_next (siter)) {
|
|
|
59ad60 |
+ CamelIMAPXServer *imapx_server = siter->data;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ job = camel_imapx_server_ref_job (imapx_server, folder, job_type, uid);
|
|
|
59ad60 |
+ if (job)
|
|
|
59ad60 |
+ break;
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ g_list_free_full (servers, g_object_unref);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
+ return job;
|
|
|
59ad60 |
+}
|
|
|
59ad60 |
diff -up evolution-data-server-3.8.5/camel/camel-imapx-store.h.imapx-conn-manager-ext evolution-data-server-3.8.5/camel/camel-imapx-store.h
|
|
|
59ad60 |
--- evolution-data-server-3.8.5/camel/camel-imapx-store.h.imapx-conn-manager-ext 2013-07-23 13:57:56.000000000 +0200
|
|
|
59ad60 |
+++ evolution-data-server-3.8.5/camel/camel-imapx-store.h 2014-05-13 14:17:43.119983665 +0200
|
|
|
59ad60 |
@@ -55,6 +55,9 @@
|
|
|
59ad60 |
|
|
|
59ad60 |
G_BEGIN_DECLS
|
|
|
59ad60 |
|
|
|
59ad60 |
+/* Avoid a circular reference. */
|
|
|
59ad60 |
+struct _CamelIMAPXJob;
|
|
|
59ad60 |
+
|
|
|
59ad60 |
typedef struct _CamelIMAPXStore CamelIMAPXStore;
|
|
|
59ad60 |
typedef struct _CamelIMAPXStoreClass CamelIMAPXStoreClass;
|
|
|
59ad60 |
typedef struct _CamelIMAPXStorePrivate CamelIMAPXStorePrivate;
|
|
|
59ad60 |
@@ -93,6 +96,7 @@ GType camel_imapx_store_get_type (void)
|
|
|
59ad60 |
CamelIMAPXServer *
|
|
|
59ad60 |
camel_imapx_store_get_server (CamelIMAPXStore *store,
|
|
|
59ad60 |
const gchar *folder_name,
|
|
|
59ad60 |
+ gboolean for_expensive_job,
|
|
|
59ad60 |
GCancellable *cancellable,
|
|
|
59ad60 |
GError **error);
|
|
|
59ad60 |
void camel_imapx_store_op_done (CamelIMAPXStore *istore,
|
|
|
59ad60 |
@@ -106,6 +110,16 @@ void camel_imapx_store_set_quota_info
|
|
|
59ad60 |
(CamelIMAPXStore *store,
|
|
|
59ad60 |
const gchar *quota_root_name,
|
|
|
59ad60 |
const CamelFolderQuotaInfo *info);
|
|
|
59ad60 |
+void camel_imapx_store_set_authenticating_concurrent_connection
|
|
|
59ad60 |
+ (CamelIMAPXStore *store,
|
|
|
59ad60 |
+ gboolean is_concurrent_connection);
|
|
|
59ad60 |
+gboolean camel_imapx_store_get_authenticating_concurrent_connection
|
|
|
59ad60 |
+ (CamelIMAPXStore *store);
|
|
|
59ad60 |
+struct _CamelIMAPXJob *
|
|
|
59ad60 |
+ camel_imapx_store_ref_job (CamelIMAPXStore *imapx_store,
|
|
|
59ad60 |
+ CamelFolder *folder,
|
|
|
59ad60 |
+ guint32 job_type,
|
|
|
59ad60 |
+ const gchar *uid);
|
|
|
59ad60 |
|
|
|
59ad60 |
G_END_DECLS
|
|
|
59ad60 |
|
|
|
59ad60 |
diff -up evolution-data-server-3.8.5/camel/camel-imapx-stream.c.imapx-conn-manager-ext evolution-data-server-3.8.5/camel/camel-imapx-stream.c
|
|
|
59ad60 |
--- evolution-data-server-3.8.5/camel/camel-imapx-stream.c.imapx-conn-manager-ext 2013-07-23 13:57:55.000000000 +0200
|
|
|
59ad60 |
+++ evolution-data-server-3.8.5/camel/camel-imapx-stream.c 2014-05-13 14:17:43.119983665 +0200
|
|
|
59ad60 |
@@ -34,6 +34,7 @@
|
|
|
59ad60 |
#include <camel/camel-stream-mem.h>
|
|
|
59ad60 |
|
|
|
59ad60 |
#include "camel-imapx-utils.h"
|
|
|
59ad60 |
+#include "camel-imapx-server.h"
|
|
|
59ad60 |
#include "camel-imapx-stream.h"
|
|
|
59ad60 |
|
|
|
59ad60 |
#define CAMEL_IMAPX_STREAM_GET_PRIVATE(obj) \
|
|
|
59ad60 |
@@ -92,10 +93,14 @@ imapx_stream_fill (CamelIMAPXStream *is,
|
|
|
59ad60 |
* that to be an error. But we do -- we should only be here
|
|
|
59ad60 |
* if we *know* there are data to receive. So set the error
|
|
|
59ad60 |
* accordingly */
|
|
|
59ad60 |
- if (!left)
|
|
|
59ad60 |
+ if (!left) {
|
|
|
59ad60 |
+ io (is->tagprefix, "Failed to read any bytes into buffer of size %d (from buffer size %d, last read:'%.20s')\n", (gint) (is->priv->bufsize - (is->priv->end - is->priv->buf)), is->priv->bufsize, (const gchar *) is->priv->buf);
|
|
|
59ad60 |
+
|
|
|
59ad60 |
g_set_error (
|
|
|
59ad60 |
- error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
|
|
|
59ad60 |
+ error, CAMEL_IMAPX_SERVER_ERROR, CAMEL_IMAPX_SERVER_ERROR_TRY_RECONNECT,
|
|
|
59ad60 |
_("Source stream returned no data"));
|
|
|
59ad60 |
+ }
|
|
|
59ad60 |
+
|
|
|
59ad60 |
return -1;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
}
|
|
|
59ad60 |
diff -up evolution-data-server-3.8.5/camel/camel-imapx-utils.c.imapx-conn-manager-ext evolution-data-server-3.8.5/camel/camel-imapx-utils.c
|
|
|
59ad60 |
--- evolution-data-server-3.8.5/camel/camel-imapx-utils.c.imapx-conn-manager-ext 2014-05-13 14:17:43.110983665 +0200
|
|
|
59ad60 |
+++ evolution-data-server-3.8.5/camel/camel-imapx-utils.c 2014-05-13 14:17:43.119983665 +0200
|
|
|
59ad60 |
@@ -430,8 +430,8 @@ create_initial_capabilities_table (void)
|
|
|
59ad60 |
* to free hash table
|
|
|
59ad60 |
*/
|
|
|
59ad60 |
capa_htable = g_hash_table_new_full (
|
|
|
59ad60 |
- g_str_hash,
|
|
|
59ad60 |
- g_str_equal,
|
|
|
59ad60 |
+ camel_strcase_hash,
|
|
|
59ad60 |
+ camel_strcase_equal,
|
|
|
59ad60 |
g_free,
|
|
|
59ad60 |
NULL);
|
|
|
59ad60 |
|
|
|
59ad60 |
@@ -456,7 +456,7 @@ imapx_parse_capability (CamelIMAPXStream
|
|
|
59ad60 |
GError *local_error = NULL;
|
|
|
59ad60 |
|
|
|
59ad60 |
cinfo = g_malloc0 (sizeof (*cinfo));
|
|
|
59ad60 |
- cinfo->auth_types = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, NULL);
|
|
|
59ad60 |
+ cinfo->auth_types = g_hash_table_new_full (camel_strcase_hash, camel_strcase_equal, (GDestroyNotify) g_free, NULL);
|
|
|
59ad60 |
|
|
|
59ad60 |
/* FIXME: handle auth types */
|
|
|
59ad60 |
while ((tok = camel_imapx_stream_token (stream, &token, &len, cancellable, &local_error)) != '\n' &&
|
|
|
59ad60 |
@@ -2607,10 +2607,3 @@ imapx_get_temp_uid (void)
|
|
|
59ad60 |
|
|
|
59ad60 |
return res;
|
|
|
59ad60 |
}
|
|
|
59ad60 |
-
|
|
|
59ad60 |
-void
|
|
|
59ad60 |
-camel_imapx_destroy_job_queue_info (IMAPXJobQueueInfo *jinfo)
|
|
|
59ad60 |
-{
|
|
|
59ad60 |
- g_hash_table_destroy (jinfo->folders);
|
|
|
59ad60 |
- g_free (jinfo);
|
|
|
59ad60 |
-}
|
|
|
59ad60 |
diff -up evolution-data-server-3.8.5/camel/camel-imapx-utils.h.imapx-conn-manager-ext evolution-data-server-3.8.5/camel/camel-imapx-utils.h
|
|
|
59ad60 |
--- evolution-data-server-3.8.5/camel/camel-imapx-utils.h.imapx-conn-manager-ext 2013-07-23 13:57:45.000000000 +0200
|
|
|
59ad60 |
+++ evolution-data-server-3.8.5/camel/camel-imapx-utils.h 2014-05-13 14:17:43.119983665 +0200
|
|
|
59ad60 |
@@ -365,17 +365,6 @@ gboolean camel_imapx_parse_quotaroot (st
|
|
|
59ad60 |
GError **error);
|
|
|
59ad60 |
|
|
|
59ad60 |
/* ********************************************************************** */
|
|
|
59ad60 |
-typedef struct _IMAPXJobQueueInfo {
|
|
|
59ad60 |
- guint queue_len;
|
|
|
59ad60 |
-
|
|
|
59ad60 |
- /* list of folders for which jobs are in the queue */
|
|
|
59ad60 |
- GHashTable *folders;
|
|
|
59ad60 |
-} IMAPXJobQueueInfo;
|
|
|
59ad60 |
-
|
|
|
59ad60 |
-void camel_imapx_destroy_job_queue_info
|
|
|
59ad60 |
- (IMAPXJobQueueInfo *jinfo);
|
|
|
59ad60 |
-
|
|
|
59ad60 |
-/* ********************************************************************** */
|
|
|
59ad60 |
|
|
|
59ad60 |
extern guchar imapx_specials[256];
|
|
|
59ad60 |
|
|
|
59ad60 |
diff -up evolution-data-server-3.8.5/camel/camel-service.c.imapx-conn-manager-ext evolution-data-server-3.8.5/camel/camel-service.c
|
|
|
59ad60 |
--- evolution-data-server-3.8.5/camel/camel-service.c.imapx-conn-manager-ext 2013-07-23 14:01:51.000000000 +0200
|
|
|
59ad60 |
+++ evolution-data-server-3.8.5/camel/camel-service.c 2014-05-13 14:17:43.120983665 +0200
|
|
|
59ad60 |
@@ -934,7 +934,7 @@ service_authenticate_finish (CamelServic
|
|
|
59ad60 |
g_return_val_if_fail (
|
|
|
59ad60 |
g_simple_async_result_is_valid (
|
|
|
59ad60 |
result, G_OBJECT (service), service_authenticate),
|
|
|
59ad60 |
- CAMEL_AUTHENTICATION_REJECTED);
|
|
|
59ad60 |
+ CAMEL_AUTHENTICATION_ERROR);
|
|
|
59ad60 |
|
|
|
59ad60 |
simple = G_SIMPLE_ASYNC_RESULT (result);
|
|
|
59ad60 |
async_context = g_simple_async_result_get_op_res_gpointer (simple);
|
|
|
59ad60 |
@@ -2007,12 +2007,12 @@ camel_service_authenticate_sync (CamelSe
|
|
|
59ad60 |
|
|
|
59ad60 |
g_return_val_if_fail (
|
|
|
59ad60 |
CAMEL_IS_SERVICE (service),
|
|
|
59ad60 |
- CAMEL_AUTHENTICATION_REJECTED);
|
|
|
59ad60 |
+ CAMEL_AUTHENTICATION_ERROR);
|
|
|
59ad60 |
|
|
|
59ad60 |
class = CAMEL_SERVICE_GET_CLASS (service);
|
|
|
59ad60 |
g_return_val_if_fail (
|
|
|
59ad60 |
class->authenticate_sync != NULL,
|
|
|
59ad60 |
- CAMEL_AUTHENTICATION_REJECTED);
|
|
|
59ad60 |
+ CAMEL_AUTHENTICATION_ERROR);
|
|
|
59ad60 |
|
|
|
59ad60 |
result = class->authenticate_sync (
|
|
|
59ad60 |
service, mechanism, cancellable, error);
|
|
|
59ad60 |
@@ -2096,15 +2096,15 @@ camel_service_authenticate_finish (Camel
|
|
|
59ad60 |
|
|
|
59ad60 |
g_return_val_if_fail (
|
|
|
59ad60 |
CAMEL_IS_SERVICE (service),
|
|
|
59ad60 |
- CAMEL_AUTHENTICATION_REJECTED);
|
|
|
59ad60 |
+ CAMEL_AUTHENTICATION_ERROR);
|
|
|
59ad60 |
g_return_val_if_fail (
|
|
|
59ad60 |
G_IS_ASYNC_RESULT (result),
|
|
|
59ad60 |
- CAMEL_AUTHENTICATION_REJECTED);
|
|
|
59ad60 |
+ CAMEL_AUTHENTICATION_ERROR);
|
|
|
59ad60 |
|
|
|
59ad60 |
class = CAMEL_SERVICE_GET_CLASS (service);
|
|
|
59ad60 |
g_return_val_if_fail (
|
|
|
59ad60 |
class->authenticate_finish,
|
|
|
59ad60 |
- CAMEL_AUTHENTICATION_REJECTED);
|
|
|
59ad60 |
+ CAMEL_AUTHENTICATION_ERROR);
|
|
|
59ad60 |
|
|
|
59ad60 |
return class->authenticate_finish (service, result, error);
|
|
|
59ad60 |
}
|