aboutsummaryrefslogtreecommitdiffstats
ModeNameSize
-rw-r--r--.cvsignore19logstatsplainblame
d---------CVSROOT1136logstatsplain
-rw-r--r--INDEX1385118logstatsplainblame
-rw-r--r--LEGAL10257logstatsplainblame
-rw-r--r--Makefile3172logstatsplainblame
d---------Mk449logstatsplain
-rw-r--r--README1410logstatsplainblame
d---------Templates120logstatsplain
d---------Tools108logstatsplain
d---------accessibility / atk30logstatsplain
d---------arabic72logstatsplain
d---------archivers1782logstatsplain
d---------astro1269logstatsplain
d---------audio8848logstatsplain
d---------benchmarks944logstatsplain
d---------biology1181logstatsplain
d---------cad998logstatsplain
d---------chinese2986logstatsplain
d---------comms1202logstatsplain
d---------converters1755logstatsplain
d---------databases6160logstatsplain
d---------deskutils1944logstatsplain
d---------devel22608logstatsplain
d---------dns917logstatsplain
d---------editors8137logstatsplain
d---------emulators3189logstatsplain
d---------finance508logstatsplain
d---------french351logstatsplain
d---------ftp1983logstatsplain
d---------games13657logstatsplain
d---------german783logstatsplain
d---------graphics11575logstatsplain
d---------hebrew247logstatsplain
d---------hungarian72logstatsplain
d---------irc2178logstatsplain
d---------japanese16126logstatsplain
d---------java1803logstatsplain
d---------korean2905logstatsplain
d---------lang7847logstatsplain
d---------mail8422logstatsplain
d---------math4904logstatsplain
d---------mbone507logstatsplain
d---------misc9917logstatsplain
d---------multimedia1558logstatsplain
d---------net-im903logstatsplain
d---------net-mgmt2387logstatsplain
d---------net-p2p276logstatsplain
d---------net16212logstatsplain
d---------news1961logstatsplain
d---------palm1312logstatsplain
d---------picobsd104logstatsplain
d---------polish72logstatsplain
d---------ports-mgmt290logstatsplain
d---------portuguese195logstatsplain
d---------print5715logstatsplain
d---------russian938logstatsplain
d---------science387logstatsplain
d---------security7164logstatsplain
d---------shells821logstatsplain
d---------sysutils7471logstatsplain
d---------textproc7651logstatsplain
d---------ukrainian282logstatsplain
d---------vietnamese512logstatsplain
d---------www13303logstatsplain
d---------x11-clocks1229logstatsplain
d---------x11-fm947logstatsplain
d---------x11-fonts1112logstatsplain
d---------x11-servers1794logstatsplain
d---------x11-themes844logstatsplain
d---------x11-toolkits5841logstatsplain
d---------x11-wm2677logstatsplain
d---------x115333logstatsplain
="color:#3a3935">) { cancellable = msg->cancellable; if (g_cancellable_is_cancelled (cancellable)) cancellable = NULL; else g_object_ref (cancellable); } g_mutex_unlock (mail_msg_lock); if (cancellable != NULL) { g_cancellable_cancel (cancellable); g_object_unref (cancellable); } } gboolean mail_msg_active (void) { gboolean active; g_mutex_lock (mail_msg_lock); active = g_hash_table_size (mail_msg_active_table) > 0; g_mutex_unlock (mail_msg_lock); return active; } /* **************************************** */ static GHookList cancel_hook_list; GHook * mail_cancel_hook_add (GHookFunc func, gpointer data) { GHook *hook; g_mutex_lock (mail_msg_lock); if (!cancel_hook_list.is_setup) g_hook_list_init (&cancel_hook_list, sizeof (GHook)); hook = g_hook_alloc (&cancel_hook_list); hook->func = func; hook->data = data; g_hook_append (&cancel_hook_list, hook); g_mutex_unlock (mail_msg_lock); return hook; } void mail_cancel_hook_remove (GHook *hook) { g_mutex_lock (mail_msg_lock); g_return_if_fail (cancel_hook_list.is_setup); g_hook_destroy_link (&cancel_hook_list, hook); g_mutex_unlock (mail_msg_lock); } void mail_cancel_all (void) { camel_operation_cancel_all (); g_mutex_lock (mail_msg_lock); if (cancel_hook_list.is_setup) g_hook_list_invoke (&cancel_hook_list, FALSE); g_mutex_unlock (mail_msg_lock); } static guint idle_source_id = 0; G_LOCK_DEFINE_STATIC (idle_source_id); static GAsyncQueue *main_loop_queue = NULL; static GAsyncQueue *msg_reply_queue = NULL; static GThread *main_thread = NULL; static gboolean mail_msg_idle_cb (void) { MailMsg *msg; g_return_val_if_fail (main_loop_queue != NULL, FALSE); g_return_val_if_fail (msg_reply_queue != NULL, FALSE); G_LOCK (idle_source_id); idle_source_id = 0; G_UNLOCK (idle_source_id); /* check the main loop queue */ while ((msg = g_async_queue_try_pop (main_loop_queue)) != NULL) { GCancellable *cancellable; cancellable = msg->cancellable; g_idle_add_full ( G_PRIORITY_DEFAULT, (GSourceFunc) mail_msg_submit, g_object_ref (msg->cancellable), (GDestroyNotify) g_object_unref); if (msg->info->exec != NULL) msg->info->exec (msg, cancellable, &msg->error); if (msg->info->done != NULL) msg->info->done (msg); mail_msg_unref (msg); } /* check the reply queue */ while ((msg = g_async_queue_try_pop (msg_reply_queue)) != NULL) { if (msg->info->done != NULL) msg->info->done (msg); mail_msg_check_error (msg); mail_msg_unref (msg); } return FALSE; } static void mail_msg_proxy (MailMsg *msg) { GCancellable *cancellable; cancellable = msg->cancellable; if (msg->info->desc != NULL) { gchar *text = msg->info->desc (msg); camel_operation_push_message (cancellable, "%s", text); g_free (text); } g_idle_add_full ( G_PRIORITY_DEFAULT, (GSourceFunc) mail_msg_submit, g_object_ref (msg->cancellable), (GDestroyNotify) g_object_unref); if (msg->info->exec != NULL) msg->info->exec (msg, cancellable, &msg->error); if (msg->info->desc != NULL) camel_operation_pop_message (cancellable); g_async_queue_push (msg_reply_queue, msg); G_LOCK (idle_source_id); if (idle_source_id == 0) idle_source_id = g_idle_add ( (GSourceFunc) mail_msg_idle_cb, NULL); G_UNLOCK (idle_source_id); } void mail_msg_init (void) { mail_msg_lock = g_mutex_new (); mail_msg_cond = g_cond_new (); main_loop_queue = g_async_queue_new (); msg_reply_queue = g_async_queue_new (); mail_msg_active_table = g_hash_table_new (NULL, NULL); main_thread = g_thread_self (); } static gint mail_msg_compare (const MailMsg *msg1, const MailMsg *msg2) { gint priority1 = msg1->priority; gint priority2 = msg2->priority; if (priority1 == priority2) return 0; return (priority1 < priority2) ? 1 : -1; } static gpointer create_thread_pool (gpointer data) { GThreadPool *thread_pool; gint max_threads = GPOINTER_TO_INT (data); /* once created, run forever */ thread_pool = g_thread_pool_new ( (GFunc) mail_msg_proxy, NULL, max_threads, FALSE, NULL); g_thread_pool_set_sort_function ( thread_pool, (GCompareDataFunc) mail_msg_compare, NULL); return thread_pool; } void mail_msg_main_loop_push (gpointer msg) { g_async_queue_push_sorted (main_loop_queue, msg, (GCompareDataFunc) mail_msg_compare, NULL); G_LOCK (idle_source_id); if (idle_source_id == 0) idle_source_id = g_idle_add ( (GSourceFunc) mail_msg_idle_cb, NULL); G_UNLOCK (idle_source_id); } void mail_msg_unordered_push (gpointer msg) { static GOnce once = G_ONCE_INIT; g_once (&once, (GThreadFunc) create_thread_pool, GINT_TO_POINTER (10)); g_thread_pool_push ((GThreadPool *) once.retval, msg, NULL); } void mail_msg_fast_ordered_push (gpointer msg) { static GOnce once = G_ONCE_INIT; g_once (&once, (GThreadFunc) create_thread_pool, GINT_TO_POINTER (1)); g_thread_pool_push ((GThreadPool *) once.retval, msg, NULL); } void mail_msg_slow_ordered_push (gpointer msg) { static GOnce once = G_ONCE_INIT; g_once (&once, (GThreadFunc) create_thread_pool, GINT_TO_POINTER (1)); g_thread_pool_push ((GThreadPool *) once.retval, msg, NULL); } gboolean mail_in_main_thread (void) { return (g_thread_self () == main_thread); } /* ********************************************************************** */ struct _call_msg { MailMsg base; mail_call_t type; MailMainFunc func; gpointer ret; va_list ap; EFlag *done; }; static void do_call (struct _call_msg *m, GCancellable *cancellable, GError **error) { gpointer p1, *p2, *p3, *p4, *p5; gint i1; va_list ap; G_VA_COPY (ap, m->ap); switch (m->type) { case MAIL_CALL_p_p: p1 = va_arg (ap, gpointer ); m->ret = m->func (p1); break; case MAIL_CALL_p_pp: p1 = va_arg (ap, gpointer ); p2 = va_arg (ap, gpointer ); m->ret = m->func (p1, p2); break; case MAIL_CALL_p_ppp: p1 = va_arg (ap, gpointer ); p2 = va_arg (ap, gpointer ); p3 = va_arg (ap, gpointer ); m->ret = m->func (p1, p2, p3); break; case MAIL_CALL_p_pppp: p1 = va_arg (ap, gpointer ); p2 = va_arg (ap, gpointer ); p3 = va_arg (ap, gpointer ); p4 = va_arg (ap, gpointer ); m->ret = m->func (p1, p2, p3, p4); break; case MAIL_CALL_p_ppppp: p1 = va_arg (ap, gpointer ); p2 = va_arg (ap, gpointer ); p3 = va_arg (ap, gpointer ); p4 = va_arg (ap, gpointer ); p5 = va_arg (ap, gpointer ); m->ret = m->func (p1, p2, p3, p4, p5); break; case MAIL_CALL_p_ppippp: p1 = va_arg (ap, gpointer ); p2 = va_arg (ap, gpointer ); i1 = va_arg (ap, gint); p3 = va_arg (ap, gpointer ); p4 = va_arg (ap, gpointer ); p5 = va_arg (ap, gpointer ); m->ret = m->func (p1, p2, i1, p3, p4, p5); break; } if (g_cancellable_is_cancelled (cancellable)) { if (cancel_activity) cancel_activity (cancellable); } else { if (complete_activity) complete_activity (cancellable); } if (m->done != NULL) e_flag_set (m->done); } static MailMsgInfo mail_call_info = { sizeof (struct _call_msg), (MailMsgDescFunc) NULL, (MailMsgExecFunc) do_call, (MailMsgDoneFunc) NULL, (MailMsgFreeFunc) NULL }; gpointer mail_call_main (mail_call_t type, MailMainFunc func, ...) { GCancellable *cancellable; struct _call_msg *m; gpointer ret; va_list ap; va_start (ap, func); m = mail_msg_new (&mail_call_info); m->type = type; m->func = func; G_VA_COPY (m->ap, ap); cancellable = m->base.cancellable; if (mail_in_main_thread ()) do_call (m, cancellable, &m->base.error); else { mail_msg_ref (m); m->done = e_flag_new (); mail_msg_main_loop_push (m); e_flag_wait (m->done); e_flag_free (m->done); } va_end (ap); ret = m->ret; mail_msg_unref (m); return ret; } void mail_mt_set_backend (gchar *backend) { shell_builtin_backend = backend; }