[libgnome-keyring] Workaround for problem with endless loop during blocking operations.



commit 942ff4eae19732d9f5fd0d549385a7f2d9842444
Author: Stef Walter <stef memberwebs com>
Date:   Fri Apr 9 18:39:38 2010 +0000

    Workaround for problem with endless loop during blocking operations.
    
    Research done by Hiroyuki Ikezoe
    
    This is due to a bug in libdbus where the pending call is completed
    without the relevant callback being called when used in certain
    threading situations.
    
    Fixes bug #606902

 library/gkr-operation.c |   14 +++++++++++++-
 1 files changed, 13 insertions(+), 1 deletions(-)
---
diff --git a/library/gkr-operation.c b/library/gkr-operation.c
index 214ecc7..9f49e73 100644
--- a/library/gkr-operation.c
+++ b/library/gkr-operation.c
@@ -363,13 +363,25 @@ gkr_operation_request (GkrOperation *op, DBusMessage *req)
 GnomeKeyringResult
 gkr_operation_block (GkrOperation *op)
 {
+	DBusPendingCall *pending;
 	g_return_val_if_fail (op, BROKEN);
 
 	gkr_operation_ref (op);
 
 	while ((int) gkr_operation_get_result (op) == INCOMPLETE) {
 		if (op->pending) {
-			dbus_pending_call_block (op->pending);
+			/*
+			 * DBus has strange behavior that can complete a pending call
+			 * in another thread and somehow does this without calling our
+			 * on_pending_call_notify. So guard against this brokenness.
+			 */
+			pending = op->pending;
+			dbus_pending_call_block (pending);
+			if (op->pending == pending) {
+				g_return_val_if_fail (dbus_pending_call_get_completed (pending), BROKEN);
+				on_pending_call_notify (pending, op);
+				g_assert (op->pending != pending);
+			}
 		} else if (op->prompting) {
 			dbus_connection_flush (op->conn);
 			while (op->prompting && (int) gkr_operation_get_result (op) == INCOMPLETE) {



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