Tinymail hangs when cancelling a connection



Hi,

I've just discovered that tinymail hangs when issuing two connections in a row using tny_camel_account_set_online. The error could be seen in this trace

Thread 1 (Thread 1076438432 (LWP 2956)):
#0  0x4071e334 in pthread_cond_wait@@GLIBC_2.4 () from /lib/libpthread.so.0
#1 0x400f3a30 in on_set_online_done (self=0x177100, account=0x18b240, err=0x308098, user_data=0x2b6d58)
    at tny-camel-account.c:1726
#2 0x400f945c in cancelled_conn (user_data=0x2ffc30) at tny-camel-store-account.c:1777 #3 0x40dd2098 in g_idle_dispatch (source=0xfffffffc, callback=0x400f93dc <cancelled_conn>, user_data=0x0)
    at gmain.c:3928
#4 0x40dce570 in IA__g_main_context_dispatch (context=0xd6a20) at gmain.c:2045 #5 0x40dd043c in g_main_context_iterate (context=0xd6a20, block=1, dispatch=1, self=0x0) at gmain.c:2677
#6  0x40dd07b4 in IA__g_main_loop_run (loop=0xbf658) at gmain.c:2881
#7  0x408b63d8 in IA__gtk_main () at gtkmain.c:1155
#8  0x0002da30 in main (argc=1, argv=0xbea9d6d4) at modest-main.c:158
#9  0x40e5010c in __libc_start_main () from /lib/libc.so.6
#10 0x0001f830 in _start ()

You see it? The cancelled_conn is issued in an idle, and it calls execute_callback with depth 10, which means that the user callback will be called in an idle. After that it waits in a GCond. What happens is that the idle with the call to the user callback will never happen because the main loop is actually stopped in the g_cond_wait, so the g_cond_wait will wait forever. It's a simple fix for this, just to call the execute_callback with depth 0 if the connection was cancelled. See the patch attached.

Br
Index: tny-camel-account.c
===================================================================
--- tny-camel-account.c	(revision 2980)
+++ tny-camel-account.c	(working copy)
@@ -1716,7 +1716,12 @@
 	info->condition = g_cond_new ();
 	info->had_callback = FALSE;
 
-	execute_callback (/* info->depth */ 10, G_PRIORITY_HIGH, 
+	/* If the connection was cancelled we can not execute this in
+	   an idle because we're currently in the main loop. If we try
+	   to execute it in an idle the following g_cond_wait will
+	   never succeed because the idle won't be executed never
+	   (we're in the main loop) */
+	execute_callback ((info->cancel) ? 0 : 10, G_PRIORITY_HIGH, 
 		on_set_online_done_idle_func, 
 		info, on_set_online_done_destroy_func);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]