From: Mike Gorse Date: Mon, 19 Sep 2011 21:05:58 +0000 (-0500) Subject: BGO#658013: Add timeout to check for disconnect on a key listener X-Git-Tag: AT_SPI2_ATK_2_1_92~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ecba2419cee6cb34695b24bc38664409a28eaa0e;p=platform%2Fupstream%2Fat-spi2-atk.git BGO#658013: Add timeout to check for disconnect on a key listener For some reason, if the dbus connection goes away during a call to NotifyListenersSync, the DBusPendingCall is not notified. This may be a libdbus bug. Working around the issue by adding a timeout that will check for a disconnect and abort the call as needed. --- diff --git a/atk-adaptor/event.c b/atk-adaptor/event.c index 6add6e7..79c2884 100644 --- a/atk-adaptor/event.c +++ b/atk-adaptor/event.c @@ -53,8 +53,10 @@ static gint atk_bridge_focus_tracker_id; typedef struct _SpiReentrantCallClosure { + DBusConnection *bus; GMainLoop *loop; DBusMessage *reply; + guint timeout; } SpiReentrantCallClosure; static void @@ -81,6 +83,17 @@ set_reply (DBusPendingCall * pending, void *user_data) g_main_loop_quit (closure->loop); } +static gboolean +timeout_reply (void *data) +{ + SpiReentrantCallClosure *closure = data; + + if (!dbus_connection_get_is_connected (closure->bus)) + g_main_loop_quit (closure->loop); + closure->timeout = -1; + return FALSE; +} + static DBusMessage * send_and_allow_reentry (DBusConnection * bus, DBusMessage * message) { @@ -90,16 +103,21 @@ send_and_allow_reentry (DBusConnection * bus, DBusMessage * message) main_context = (g_getenv ("AT_SPI_CLIENT") ? NULL : spi_global_app_data->main_context); + closure.bus = bus; closure.loop = g_main_loop_new (main_context, FALSE); + closure.reply = NULL; switch_main_context (main_context); - if (!dbus_connection_send_with_reply (bus, message, &pending, -1) || !pending) + if (!dbus_connection_send_with_reply (bus, message, &pending, 9000) || !pending) { switch_main_context (NULL); return NULL; } dbus_pending_call_set_notify (pending, set_reply, (void *) &closure, NULL); + closure.timeout = g_timeout_add (500, timeout_reply, &closure); g_main_loop_run (closure.loop); + if (closure.timeout != -1) + g_source_remove (closure.timeout); g_main_loop_unref (closure.loop); return closure.reply;