aboutsummaryrefslogtreecommitdiffstats
path: root/mail/mail-session.c
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2007-12-21 01:58:09 +0800
committerMatthew Barnes <mbarnes@src.gnome.org>2007-12-21 01:58:09 +0800
commit538be0680e04babfa4a42132e8c6188c4b23efa2 (patch)
treec73a9f317d0c392fd397f68908d0a49e2398ae37 /mail/mail-session.c
parentc4edfbcd4477ae7e136537bf11d337da1c7ebfdb (diff)
downloadgsoc2013-evolution-538be0680e04babfa4a42132e8c6188c4b23efa2.tar
gsoc2013-evolution-538be0680e04babfa4a42132e8c6188c4b23efa2.tar.gz
gsoc2013-evolution-538be0680e04babfa4a42132e8c6188c4b23efa2.tar.bz2
gsoc2013-evolution-538be0680e04babfa4a42132e8c6188c4b23efa2.tar.lz
gsoc2013-evolution-538be0680e04babfa4a42132e8c6188c4b23efa2.tar.xz
gsoc2013-evolution-538be0680e04babfa4a42132e8c6188c4b23efa2.tar.zst
gsoc2013-evolution-538be0680e04babfa4a42132e8c6188c4b23efa2.zip
** Fixes bug #362638
2007-12-20 Matthew Barnes <mbarnes@redhat.com> ** Fixes bug #362638 * calendar/gui/alarm-notify/alarm-notify.c: * calendar/gui/alarm-notify/alarm-notify.h: * calendar/gui/alarm-notify/alarm-queue.c: Rewrite message passing to use GThreadPool instead of EThread. * mail/mail-mt.h: Overhaul the message passing API: - Define a MailMsg type as the base message struct. - Define types for the various callback functions. - Add a priority value to each message (not yet used). - Add a reference count to each message. - Define a MailMsgInfo type for the virtual function table. - Record the size of message sub-types in MailMsgInfo. - New/changed functions: mail_msg_new() - Easier to use. mail_msg_ref() - Increase reference count. mail_msg_unref() - Decrease reference count. mail_msg_main_loop_push() } mail_msg_unordered_push() } Submit MailMsgs to various mail_msg_fast_ordered_push() } message-processing threads. mail_msg_slow_ordered_push() } * mail/mail-mt.c (mail_msg_new): Use GSlice for memory allocation. * mail/mail-mt.c (mail_msg_ref), (mail_msg_unref): New functions increment/decrement a MailMsg's reference count. * mail/mail-mt.c (mail_cancel_hood_add), (mail_cancel_hook_remove): Convert the 'cancel_hook_list' from an EDList to a GHookList and modify the API accordingly. * mail/mail-mt.c: Use GThreadPools instead of EThreads. Use GAsyncQueues instead of EMsgPorts. * mail/em-composer-utils.c: * mail/em-folder-browser.c: * mail/em-folder-properties.c: * mail/em-folder-tree.c: * mail/em-folder-utils.c: * mail/em-folder-view.c: * mail/em-format-html-print.c: * mail/em-format-html.c: * mail/em-subscribe-editor.c: * mail/em-sync-stream.c: * mail/importers/elm-importer.c: * mail/importers/mail-importer.c: * mail/importers/pine-importer.c: * mail/mail-component.c: * mail/mail-folder-cache.c: * mail/mail-mt.c: * mail/mail-ops.c: * mail/mail-ops.h: * mail/mail-send-recv.c: * mail/mail-session.c: * mail/mail-vfolder.c: * mail/message-list.c: * plugins/folder-unsubscribe/folder-unsubscribe.c: * plugins/groupwise-features/share-folder-common.c: * plugins/exchange-operations/exchange-folder.c: * plugins/mark-all-read/mark-all-read.c: * plugins/mailing-list-actions/mailing-list-actions.c: * plugins/itip-formatter/itip-formatter.c: * plugins/save-attachments/save-attachments.c: Use the new MailMsg API for messages. svn path=/trunk/; revision=34730
Diffstat (limited to 'mail/mail-session.c')
-rw-r--r--mail/mail-session.c176
1 files changed, 87 insertions, 89 deletions
diff --git a/mail/mail-session.c b/mail/mail-session.c
index c833b6a849..6dd7d5a8cd 100644
--- a/mail/mail-session.c
+++ b/mail/mail-session.c
@@ -35,7 +35,7 @@
#include <libgnome/gnome-sound.h>
#include <libedataserverui/e-passwords.h>
-#include <libedataserver/e-msgport.h>
+#include <libedataserver/e-flag.h>
#include <camel/camel.h> /* FIXME: this is where camel_init is defined, it shouldn't include everything else */
#include <camel/camel-filter-driver.h>
@@ -265,21 +265,22 @@ forget_password (CamelSession *session, CamelService *service, const char *domai
/* ********************************************************************** */
-static GtkDialog *message_dialog;
-static EDList message_list = E_DLIST_INITIALISER(message_list);
+static gpointer user_message_dialog;
+static GQueue user_message_queue = { NULL, NULL, 0 };
struct _user_message_msg {
- struct _mail_msg msg;
+ MailMsg base;
CamelSessionAlertType type;
char *prompt;
+ EFlag *done;
unsigned int allow_cancel:1;
unsigned int result:1;
unsigned int ismain:1;
};
-static void do_user_message (struct _mail_msg *mm);
+static void user_message_exec (struct _user_message_msg *m);
/* clicked, send back the reply */
static void
@@ -287,126 +288,122 @@ user_message_response (GtkDialog *dialog, int button, struct _user_message_msg *
{
gtk_widget_destroy ((GtkWidget *) dialog);
- message_dialog = NULL;
+ user_message_dialog = NULL;
/* if !allow_cancel, then we've already replied */
if (m->allow_cancel) {
m->result = button == GTK_RESPONSE_OK;
- e_msgport_reply((EMsg *)m);
+ e_flag_set (m->done);
}
/* check for pendings */
- if ((m = (struct _user_message_msg *)e_dlist_remhead(&message_list)))
- do_user_message((struct _mail_msg *)m);
+ if (!g_queue_is_empty (&user_message_queue)) {
+ m = g_queue_pop_head (&user_message_queue);
+ user_message_exec (m);
+ mail_msg_unref (m);
+ }
}
static void
-user_message_destroy_notify (struct _user_message_msg *m, GObject *deadbeef)
+user_message_exec (struct _user_message_msg *m)
{
- message_dialog = NULL;
-}
-
-/* This is kinda ugly/inefficient, but oh well, it works */
-static const char *error_type[] = {
- "mail:session-message-info", "mail:session-message-warning", "mail:session-message-error",
- "mail:session-message-info-cancel", "mail:session-message-warning-cancel", "mail:session-message-error-cancel"
-};
+ const gchar *error_type;
-static void
-do_user_message (struct _mail_msg *mm)
-{
- struct _user_message_msg *m = (struct _user_message_msg *)mm;
- int type;
-
- if (!m->ismain && message_dialog != NULL) {
- e_dlist_addtail (&message_list, (EDListNode *)m);
+ if (!m->ismain && user_message_dialog != NULL) {
+ g_queue_push_tail (&user_message_queue, mail_msg_ref (m));
return;
}
switch (m->type) {
- case CAMEL_SESSION_ALERT_INFO:
- type = 0;
- break;
- case CAMEL_SESSION_ALERT_WARNING:
- type = 1;
- break;
- case CAMEL_SESSION_ALERT_ERROR:
- type = 2;
- break;
- default:
- type = 0;
+ case CAMEL_SESSION_ALERT_INFO:
+ error_type = m->allow_cancel ?
+ "mail:session-message-info-cancel" :
+ "mail:session-message-info";
+ break;
+ case CAMEL_SESSION_ALERT_WARNING:
+ error_type = m->allow_cancel ?
+ "mail:session-message-warning-cancel" :
+ "mail:session-message-warning";
+ break;
+ case CAMEL_SESSION_ALERT_ERROR:
+ error_type = m->allow_cancel ?
+ "mail:session-message-error-cancel" :
+ "mail:session-message-error";
+ break;
+ default:
+ g_assert_not_reached ();
}
- if (m->allow_cancel)
- type += 3;
-
- message_dialog = (GtkDialog *)e_error_new(NULL, error_type[type], m->prompt, NULL);
- g_object_set ((GObject *) message_dialog, "allow_shrink", TRUE, "allow_grow", TRUE, NULL);
+ user_message_dialog = e_error_new (NULL, error_type, m->prompt, NULL);
+ g_object_set (
+ user_message_dialog, "allow_shrink", TRUE,
+ "allow_grow", TRUE, NULL);
- /* We only need to wait for the result if we allow cancel otherwise show but send result back instantly */
- if (m->allow_cancel) {
- if (m->ismain) {
- user_message_response(message_dialog, gtk_dialog_run (message_dialog), m);
- } else {
- g_signal_connect (message_dialog, "response", G_CALLBACK (user_message_response), m);
- gtk_widget_show ((GtkWidget *) message_dialog);
- }
+ /* We only need to wait for the result if we allow cancel
+ * otherwise show but send result back instantly */
+ if (m->allow_cancel && m->ismain) {
+ gint response = gtk_dialog_run (user_message_dialog);
+ user_message_response (user_message_dialog, response, m);
} else {
- g_signal_connect (message_dialog, "response", G_CALLBACK (gtk_widget_destroy), message_dialog);
- g_object_weak_ref ((GObject *) message_dialog, (GWeakNotify) user_message_destroy_notify, m);
- gtk_widget_show ((GtkWidget *) message_dialog);
- mail_msg_free(m);
+ g_signal_connect (
+ user_message_dialog, "response",
+ G_CALLBACK (user_message_response), m);
+ gtk_widget_show (user_message_dialog);
}
}
static void
-free_user_message(struct _mail_msg *mm)
+user_message_free (struct _user_message_msg *m)
{
- struct _user_message_msg *m = (struct _user_message_msg *)mm;
-
g_free(m->prompt);
+ e_flag_free(m->done);
}
-static struct _mail_msg_op user_message_op = { NULL, do_user_message, NULL, free_user_message };
+static MailMsgInfo user_message_info = {
+ sizeof (struct _user_message_msg),
+ (MailMsgDescFunc) NULL,
+ (MailMsgExecFunc) user_message_exec,
+ (MailMsgDoneFunc) NULL,
+ (MailMsgFreeFunc) user_message_free
+};
static gboolean
alert_user(CamelSession *session, CamelSessionAlertType type, const char *prompt, gboolean cancel)
{
MailSession *mail_session = MAIL_SESSION (session);
- struct _user_message_msg *m, *r;
- EMsgPort *user_message_reply = NULL;
- gboolean ret;
+ struct _user_message_msg *m;
+ gboolean result = TRUE;
if (!mail_session->interactive)
return FALSE;
- if (cancel)
- user_message_reply = e_msgport_new ();
- m = mail_msg_new (&user_message_op, user_message_reply, sizeof (*m));
- m->ismain = pthread_equal(pthread_self(), mail_gui_thread);
+ m = mail_msg_new (&user_message_info);
+ m->ismain = mail_in_main_thread ();
m->type = type;
- m->prompt = g_strdup(prompt);
+ m->prompt = g_strdup (prompt);
+ m->done = e_flag_new ();
m->allow_cancel = cancel;
- if (m->ismain)
- do_user_message((struct _mail_msg *)m);
- else {
- extern EMsgPort *mail_gui_port2;
+ if (cancel)
+ mail_msg_ref (m);
- e_msgport_put(mail_gui_port2, (EMsg *)m);
- }
+ if (m->ismain)
+ user_message_exec (m);
+ else
+ mail_msg_main_loop_push (m);
if (cancel) {
- r = (struct _user_message_msg *)e_msgport_wait(user_message_reply);
- g_return_val_if_fail (m == r, FALSE);
+ e_flag_wait (m->done);
+ result = m->result;
+ mail_msg_unref (m);
+ }
- ret = m->result;
- mail_msg_free(m);
- e_msgport_destroy(user_message_reply);
- } else
- ret = TRUE;
+ if (m->ismain) {
+ user_message_free (m);
+ mail_msg_unref (m);
+ }
- return ret;
+ return result;
}
static CamelFolder *
@@ -542,7 +539,7 @@ get_filter_driver (CamelSession *session, const char *type, CamelException *ex)
/* TODO: This is very temporary, until we have a better way to do the progress reporting,
we just borrow a dummy mail-mt thread message and hook it onto out camel thread message */
-static mail_msg_op_t ms_thread_ops_dummy = { NULL };
+static MailMsgInfo ms_thread_info_dummy = { sizeof (MailMsg) };
static void *ms_thread_msg_new(CamelSession *session, CamelSessionThreadOps *ops, unsigned int size)
{
@@ -551,7 +548,7 @@ static void *ms_thread_msg_new(CamelSession *session, CamelSessionThreadOps *ops
/* We create a dummy mail_msg, and then copy its cancellation port over to ours, so
we get cancellation and progress in common with hte existing mail code, for free */
if (msg) {
- struct _mail_msg *m = mail_msg_new(&ms_thread_ops_dummy, NULL, sizeof(struct _mail_msg));
+ MailMsg *m = mail_msg_new(&ms_thread_info_dummy);
msg->data = m;
camel_operation_unref(msg->op);
@@ -564,7 +561,7 @@ static void *ms_thread_msg_new(CamelSession *session, CamelSessionThreadOps *ops
static void ms_thread_msg_free(CamelSession *session, CamelSessionThreadMsg *m)
{
- mail_msg_free(m->data);
+ mail_msg_unref(m->data);
ms_parent_class->thread_msg_free(session, m);
}
@@ -689,22 +686,23 @@ mail_session_set_interactive (gboolean interactive)
MAIL_SESSION (session)->interactive = interactive;
if (!interactive) {
- struct _user_message_msg *um;
+ struct _user_message_msg *msg;
d(printf ("Gone non-interactive, checking for outstanding interactive tasks\n"));
e_passwords_cancel();
/* flush/cancel pending user messages */
- while ((um = (struct _user_message_msg *) e_dlist_remhead (&message_list))) {
- d(printf ("Flusing message request: %s\n", um->prompt));
- e_msgport_reply((EMsg *) um);
+ while (!g_queue_is_empty (&user_message_queue)) {
+ msg = g_queue_pop_head (&user_message_queue);
+ e_flag_set (msg->done);
+ mail_msg_unref (msg);
}
/* and the current */
- if (message_dialog) {
+ if (user_message_dialog) {
d(printf("Destroying message dialogue\n"));
- gtk_widget_destroy ((GtkWidget *) message_dialog);
+ gtk_widget_destroy ((GtkWidget *) user_message_dialog);
}
}
}