aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mail/ChangeLog11
-rw-r--r--mail/mail-mt.c133
-rw-r--r--mail/mail-mt.h12
-rw-r--r--mail/mail-session.c31
4 files changed, 182 insertions, 5 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog
index 98b20e06f2..a1df585b46 100644
--- a/mail/ChangeLog
+++ b/mail/ChangeLog
@@ -1,3 +1,14 @@
+2001-10-15 <NotZed@Ximian.com>
+
+ * mail-session.c (get_password): Proxy get-password call to main
+ thread.
+ (forget_password): same for forget_password.
+ (get_filter_driver): and same for get_filter_driver, since it uses
+ gtk objects.
+
+ * mail-mt.c (mail_call_main): new generic interface for calling
+ stuff/proxying in the gui thread.
+
2001-10-14 Jon Trowbridge <trow@ximian.com>
* e-searching-tokenizer.c (e_searching_tokenizer_clone): Share
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;
diff --git a/mail/mail-mt.h b/mail/mail-mt.h
index 07616fab50..feeddd10cc 100644
--- a/mail/mail-mt.h
+++ b/mail/mail-mt.h
@@ -71,6 +71,18 @@ gboolean mail_user_message (const char *type, const char *prompt, gboolean allow
/* forward a camel event (or other call) to the gui thread */
int mail_proxy_event(CamelObjectEventHookFunc func, CamelObject *o, void *event_data, void *data);
+/* Call a function in the gui thread, wait for it to return, type is the marshaller to use */
+typedef enum {
+ MAIL_CALL_p_p,
+ MAIL_CALL_p_ppp,
+ MAIL_CALL_p_pppp,
+ MAIL_CALL_p_ppippp,
+} mail_call_t;
+
+typedef void *(*MailMainFunc)();
+
+void *mail_call_main(mail_call_t type, MailMainFunc func, ...);
+
/* a message port that receives messages in the gui thread, used for sending port */
extern EMsgPort *mail_gui_port;
/* a message port that receives messages in the gui thread, used for the reply port */
diff --git a/mail/mail-session.c b/mail/mail-session.c
index 643f60fc42..bf8d5560c3 100644
--- a/mail/mail-session.c
+++ b/mail/mail-session.c
@@ -131,8 +131,8 @@ make_key (CamelService *service, const char *item)
}
static char *
-get_password (CamelSession *session, const char *prompt, gboolean secret,
- CamelService *service, const char *item, CamelException *ex)
+main_get_password (CamelSession *session, const char *prompt, gboolean secret,
+ CamelService *service, const char *item, CamelException *ex)
{
MailSession *mail_session = MAIL_SESSION (session);
gboolean cache = TRUE;
@@ -173,9 +173,16 @@ get_password (CamelSession *session, const char *prompt, gboolean secret,
return ans;
}
+static char *
+get_password (CamelSession *session, const char *prompt, gboolean secret,
+ CamelService *service, const char *item, CamelException *ex)
+{
+ return (char *)mail_call_main(MAIL_CALL_p_ppippp, (MailMainFunc)main_get_password,
+ session, prompt, secret, service, item, ex);
+}
+
static void
-forget_password (CamelSession *session, CamelService *service,
- const char *item, CamelException *ex)
+main_forget_password (CamelSession *session, CamelService *service, const char *item, CamelException *ex)
{
char *key = make_key (service, item);
@@ -184,6 +191,13 @@ forget_password (CamelSession *session, CamelService *service,
g_free (key);
}
+static void
+forget_password (CamelSession *session, CamelService *service, const char *item, CamelException *ex)
+{
+ mail_call_main(MAIL_CALL_p_pppp, (MailMainFunc)main_forget_password,
+ session, service, item, ex);
+}
+
static gboolean
alert_user (CamelSession *session, CamelSessionAlertType type,
const char *prompt, gboolean cancel)
@@ -317,7 +331,7 @@ get_folder (CamelFilterDriver *d, const char *uri, void *data, CamelException *e
}
static CamelFilterDriver *
-get_filter_driver (CamelSession *session, const char *type, CamelException *ex)
+main_get_filter_driver (CamelSession *session, const char *type, CamelException *ex)
{
CamelFilterDriver *driver;
RuleContext *fc;
@@ -369,6 +383,13 @@ get_filter_driver (CamelSession *session, const char *type, CamelException *ex)
return driver;
}
+static CamelFilterDriver *
+get_filter_driver (CamelSession *session, const char *type, CamelException *ex)
+{
+ return (CamelFilterDriver *)mail_call_main(MAIL_CALL_p_ppp, (MailMainFunc)main_get_filter_driver,
+ session, type, ex);
+}
+
char *
mail_session_get_password (const char *url_string)
{