aboutsummaryrefslogtreecommitdiffstats
path: root/mail/mail-mt.c
diff options
context:
space:
mode:
Diffstat (limited to 'mail/mail-mt.c')
-rw-r--r--mail/mail-mt.c133
1 files changed, 133 insertions, 0 deletions
diff --git a/mail/mail-mt.c b/mail/mail-mt.c
index cf3e1878db..e9803a80e3 100644
--- a/mail/mail-mt.c
+++ b/mail/mail-mt.c
@@ -32,6 +32,7 @@
#include "mail-mt.h"
/*#define MALLOC_CHECK*/
+#define LOG_OPS
#define d(x)
static void set_stop(int sensitive);
@@ -57,6 +58,10 @@ struct _mail_msg_priv {
static GdkPixbuf *progress_icon[2] = { NULL, NULL };
/* mail_msg stuff */
+#ifdef LOG_OPS
+static FILE *log;
+#endif
+
static unsigned int mail_msg_seq; /* sequence number of each message */
static GHashTable *mail_msg_active; /* table of active messages, must hold mail_msg_lock to access */
static pthread_mutex_t mail_msg_lock = PTHREAD_MUTEX_INITIALIZER;
@@ -72,6 +77,16 @@ void *mail_msg_new(mail_msg_op_t *ops, EMsgPort *reply_port, size_t size)
MAIL_MT_LOCK(mail_msg_lock);
+#ifdef LOG_OPS
+ if (log == NULL && getenv("EVOLUTION_MAIL_LOG_OPS") != NULL) {
+ time_t now = time(0);
+
+ log = fopen("evolution-mail-ops.log", "w+");
+ setvbuf(log, NULL, _IOLBF, 0);
+ fprintf(log, "Started evolution-mail: %s\n", ctime(&now));
+ g_warning("Logging mail operations to evolution-mail-ops.log");
+ }
+#endif
msg = g_malloc0(size);
msg->ops = ops;
msg->seq = mail_msg_seq++;
@@ -84,6 +99,10 @@ void *mail_msg_new(mail_msg_op_t *ops, EMsgPort *reply_port, size_t size)
d(printf("New message %p\n", msg));
+#ifdef LOG_OPS
+ if (log)
+ fprintf(log, "%p: New\n", msg);
+#endif
MAIL_MT_UNLOCK(mail_msg_lock);
return msg;
@@ -137,6 +156,10 @@ void mail_msg_free(void *msg)
MAIL_MT_LOCK(mail_msg_lock);
+#ifdef LOG_OPS
+ if (log)
+ fprintf(log, "%p: Free\n", msg);
+#endif
g_hash_table_remove(mail_msg_active, (void *)m->seq);
pthread_cond_broadcast(&mail_msg_cond);
@@ -305,6 +328,11 @@ mail_msgport_replied(GIOChannel *source, GIOCondition cond, void *d)
checkmem(m->priv);
#endif
+#ifdef LOG_OPS
+ if (log)
+ fprintf(log, "%p: Replied to GUI thread\n", m);
+#endif
+
if (m->ops->reply_msg)
m->ops->reply_msg(m);
mail_msg_check_error(m);
@@ -327,6 +355,11 @@ mail_msgport_received(GIOChannel *source, GIOCondition cond, void *d)
checkmem(m->priv);
#endif
+#ifdef LOG_OPS
+ if (log)
+ fprintf(log, "%p: Received at GUI thread\n", m);
+#endif
+
if (m->ops->receive_msg)
m->ops->receive_msg(m);
if (m->msg.reply_port)
@@ -369,11 +402,21 @@ mail_msg_received(EThread *e, EMsg *msg, void *data)
if (m->ops->describe_msg) {
char *text = m->ops->describe_msg(m, FALSE);
+#ifdef LOG_OPS
+ if (log)
+ fprintf(log, "%p: Received at thread %ld: '%s'\n", m, pthread_self(), text);
+#endif
+
d(printf("message received at thread\n"));
camel_operation_register(m->cancel);
camel_operation_start(m->cancel, "%s", text);
g_free(text);
}
+#ifdef LOG_OPS
+ else
+ if (log)
+ fprintf(log, "%p: Received at thread %ld\n", m, pthread_self());
+#endif
if (m->ops->receive_msg) {
mail_enable_stop();
@@ -767,6 +810,96 @@ int mail_proxy_event(CamelObjectEventHookFunc func, CamelObject *o, void *event_
}
/* ********************************************************************** */
+
+struct _call_msg {
+ struct _mail_msg msg;
+ mail_call_t type;
+ MailMainFunc func;
+ void *ret;
+ va_list ap;
+};
+
+static void
+do_call(struct _mail_msg *mm)
+{
+ struct _call_msg *m = (struct _call_msg *)mm;
+ void *p1, *p2, *p3, *p4, *p5;
+ int i1;
+ va_list ap = m->ap;
+
+ switch(m->type) {
+ case MAIL_CALL_p_p:
+ p1 = va_arg(ap, void *);
+ m->ret = m->func(p1);
+ break;
+ case MAIL_CALL_p_ppp:
+ p1 = va_arg(ap, void *);
+ p2 = va_arg(ap, void *);
+ p3 = va_arg(ap, void *);
+ m->ret = m->func(p1, p2, p3);
+ break;
+ case MAIL_CALL_p_pppp:
+ p1 = va_arg(ap, void *);
+ p2 = va_arg(ap, void *);
+ p3 = va_arg(ap, void *);
+ p4 = va_arg(ap, void *);
+ m->ret = m->func(p1, p2, p3, p4);
+ break;
+ case MAIL_CALL_p_ppippp:
+ p1 = va_arg(ap, void *);
+ p2 = va_arg(ap, void *);
+ i1 = va_arg(ap, int);
+ p3 = va_arg(ap, void *);
+ p4 = va_arg(ap, void *);
+ p5 = va_arg(ap, void *);
+ m->ret = m->func(p1, p2, i1, p3, p4, p5);
+ break;
+ }
+}
+
+struct _mail_msg_op mail_call_op = {
+ NULL,
+ do_call,
+ NULL,
+ NULL,
+};
+
+void *mail_call_main(mail_call_t type, MailMainFunc func, ...)
+{
+ struct _call_msg *m;
+ void *ret;
+ va_list ap;
+ EMsgPort *reply = NULL;
+ int ismain = pthread_self() == mail_gui_thread;
+
+ va_start(ap, func);
+
+ if (!ismain)
+ reply = e_msgport_new();
+
+ m = mail_msg_new(&mail_call_op, reply, sizeof(*m));
+ m->type = type;
+ m->func = func;
+ m->ap = ap;
+
+ if (!ismain) {
+ e_msgport_put(mail_gui_port, (EMsg *)m);
+ e_msgport_wait(reply);
+ e_msgport_destroy(reply);
+ } else {
+ do_call(&m->msg);
+ }
+
+ va_end(ap);
+
+ ret = m->ret;
+ mail_msg_free(m);
+
+ return ret;
+}
+
+
+/* ********************************************************************** */
/* locked via status_lock */
static int busy_state;