diff options
-rw-r--r-- | mail/ChangeLog | 11 | ||||
-rw-r--r-- | mail/mail-mt.c | 133 | ||||
-rw-r--r-- | mail/mail-mt.h | 12 | ||||
-rw-r--r-- | mail/mail-session.c | 31 |
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) { |