return OSSO_OK;
}
-
-
-
-static gint
-on_send_receive(GArray *arguments, gpointer data, osso_rpc_t * retval)
-{
+static void
+on_send_receive_performer(gboolean canceled,
+ GError *err,
+ GtkWindow *parent_window,
+ TnyAccount *account,
+ gpointer user_data)
+{
ModestConnectedVia connect_when;
+ if (err || canceled) {
+ g_idle_add (notify_error_in_dbus_callback, NULL);
+ return;
+ }
+
connect_when = modest_conf_get_int (modest_runtime_get_conf (),
MODEST_CONF_UPDATE_WHEN_CONNECTED_BY, NULL);
same as the one specified by the user */
if (connect_when == MODEST_CONNECTED_VIA_ANY ||
connect_when == modest_platform_get_current_connection ()) {
- /* Use g_idle to context-switch into the application's thread: */
g_idle_add (on_idle_send_receive, NULL);
} else {
/* We need this to allow modest to finish */
g_idle_add (notify_error_in_dbus_callback, NULL);
}
+}
+
+
+static gint
+on_send_receive(GArray *arguments, gpointer data, osso_rpc_t * retval)
+{
+ TnyDevice *device = modest_runtime_get_device ();
+
+ if (!tny_device_is_online (device))
+ modest_platform_connect_and_perform (NULL, FALSE, NULL, on_send_receive_performer, NULL);
+ else
+ on_send_receive_performer (FALSE, NULL, NULL, NULL, NULL);
return OSSO_OK;
}
} else {
retval = MODEST_CONNECTED_VIA_ANY;
}
- }
-
+ }
g_object_unref (iap);
}
#else
GQueue *op_queue;
GMutex *queue_lock;
guint op_id;
+ guint queue_empty_handler;
};
#define MODEST_MAIL_OPERATION_QUEUE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
MODEST_TYPE_MAIL_OPERATION_QUEUE, \
priv->op_queue = g_queue_new ();
priv->queue_lock = g_mutex_new ();
priv->op_id = 0;
+ priv->queue_empty_handler = 0;
}
static void
mail_op, MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED);
}
+static gboolean
+notify_queue_empty (gpointer user_data)
+{
+ ModestMailOperationQueue *self = (ModestMailOperationQueue *) user_data;
+ ModestMailOperationQueuePrivate *priv;
+ guint num_elements;
+
+ priv = MODEST_MAIL_OPERATION_QUEUE_GET_PRIVATE(self);
+
+ g_mutex_lock (priv->queue_lock);
+ num_elements = priv->op_queue->length;
+ g_mutex_unlock (priv->queue_lock);
+
+ /* We re-check again that the queue is empty. It could happen
+ that we had issued a tny_send_queue_flush before the send
+ queue could add a mail operation to the queue as a response
+ to the "start-queue" signal, because that signal is issued
+ by tinymail in the main loop. Therefor it could happen that
+ we emit the queue-empty signal while a send-queue is still
+ waiting for the "start-queue" signal from tinymail, so the
+ send queue will never try to send the items because modest
+ is finalized before */
+ if (num_elements == 0) {
+ gdk_threads_enter ();
+ g_signal_emit (self, signals[QUEUE_EMPTY_SIGNAL], 0);
+ gdk_threads_leave ();
+ }
+
+ return FALSE;
+}
+
+
void
modest_mail_operation_queue_remove (ModestMailOperationQueue *self,
ModestMailOperation *mail_op)
{
ModestMailOperationQueuePrivate *priv;
ModestMailOperationStatus status;
+ guint num_elements;
g_return_if_fail (MODEST_IS_MAIL_OPERATION_QUEUE (self));
g_return_if_fail (MODEST_IS_MAIL_OPERATION (mail_op));
g_mutex_lock (priv->queue_lock);
g_queue_remove (priv->op_queue, mail_op);
+ num_elements = priv->op_queue->length;
g_mutex_unlock (priv->queue_lock);
MODEST_DEBUG_BLOCK (print_queue_item (mail_op, "remove"););
}
/* Free object */
-
- /* We do not own the last reference when this operation is deleted
- * as response to a progress changed signal from the mail operation
- * itself, in which case the glib signal system owns a reference
- * until the signal emission is complete. armin. */
- /* modest_runtime_verify_object_last_ref (mail_op, ""); */
g_object_unref (G_OBJECT (mail_op));
- /* Emit the queue empty-signal */
- g_signal_emit (self, signals[QUEUE_EMPTY_SIGNAL], 0);
+ /* Emit the queue empty-signal. See the function to know why
+ we emit it in an idle */
+ if (num_elements == 0) {
+ if (priv->queue_empty_handler) {
+ g_source_remove (priv->queue_empty_handler);
+ priv->queue_empty_handler = 0;
+ }
+ priv->queue_empty_handler = g_idle_add_full (G_PRIORITY_LOW,
+ notify_queue_empty,
+ self, NULL);
+ }
}
guint
static TnyAccount*
create_tny_account (ModestTnyAccountStore *self,
const gchar *name,
- TnyAccountType type)
+ TnyAccountType type,
+ gboolean notify)
{
TnyAccount *account = NULL;
ModestTnyAccountStorePrivate *priv = NULL;
tny_account_get_id (account));
/* Install a signal handler that will refresh the
- account the first time it becomes online */
- priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
- G_OBJECT (account),
- "connection_status_changed",
- G_CALLBACK (connection_status_changed),
- self);
-
- /* Set the account store */
+ account the first time it becomes online. Do this
+ only if we're adding a new account while the
+ program is running (we do not want to do this
+ allways) */
+ if (type == TNY_ACCOUNT_TYPE_STORE && notify)
+ priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
+ G_OBJECT (account),
+ "connection_status_changed",
+ G_CALLBACK (connection_status_changed),
+ self);
+
+ /* Set the account store */
g_object_set_data (G_OBJECT(account), "account_store", self);
} else {
g_printerr ("modest: failed to create account for %s\n", name);
priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self);
/* Get the server and the transport account */
- store_account = create_tny_account (self, account, TNY_ACCOUNT_TYPE_STORE);
+ store_account = create_tny_account (self, account, TNY_ACCOUNT_TYPE_STORE, notify);
if (!store_account || !TNY_IS_ACCOUNT(store_account)) {
g_warning ("%s: failed to create store account", __FUNCTION__);
return;
}
- transport_account = create_tny_account (self, account, TNY_ACCOUNT_TYPE_TRANSPORT);
+ transport_account = create_tny_account (self, account, TNY_ACCOUNT_TYPE_TRANSPORT, notify);
if (!transport_account || !TNY_IS_ACCOUNT(transport_account)) {
g_warning ("%s: failed to create transport account", __FUNCTION__);
g_object_unref (store_account);
gchar *account_name;
gboolean poke_status;
gboolean interactive;
+ ModestMailOperation *mail_op;
} SendReceiveInfo;
static void
TnyAccount *account,
gpointer user_data)
{
- ModestMailOperation *mail_op;
SendReceiveInfo *info;
info = (SendReceiveInfo *) user_data;
NULL, dgettext("ke-recv",
"cerm_device_memory_full"));
}
+ if (info->mail_op) {
+ modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
+ info->mail_op);
+ }
goto clean;
}
if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
}
-
- mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
- modest_ui_actions_disk_operations_error_handler,
- NULL, NULL);
if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
- g_signal_connect (G_OBJECT(mail_op), "operation-finished",
+ g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
G_CALLBACK (on_send_receive_finished),
info->win);
/* Send & receive. */
- modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
- modest_mail_operation_update_account (mail_op, info->account_name, info->poke_status, info->interactive,
+ modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
(info->win) ? retrieve_all_messages_cb : NULL,
new_messages_arrived, info->win);
- g_object_unref (G_OBJECT (mail_op));
clean:
/* Frees */
+ if (info->mail_op)
+ g_object_unref (G_OBJECT (info->mail_op));
if (info->account_name)
g_free (info->account_name);
if (info->win)
info->interactive = interactive;
info->account = modest_tny_account_store_get_server_account (acc_store, acc_name,
TNY_ACCOUNT_TYPE_STORE);
+ /* We need to create the operation here, because otherwise it
+ could happen that the queue emits the queue-empty signal
+ while we're trying to connect the account */
+ info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
+ modest_ui_actions_disk_operations_error_handler,
+ NULL, NULL);
+ modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
/* Invoke the connect and perform */
modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,