Index: gnome-keyring-daemon.c =================================================================== RCS file: /cvs/gnome/gnome-keyring/gnome-keyring-daemon.c,v retrieving revision 1.25 diff -u -p -u -r1.25 gnome-keyring-daemon.c --- gnome-keyring-daemon.c 26 Oct 2005 07:50:14 -0000 1.25 +++ gnome-keyring-daemon.c 9 May 2006 20:41:02 -0000 @@ -2227,6 +2227,98 @@ launch_ask_helper (GnomeKeyringAsk *ask, return res; } +typedef struct { + GnomeKeyringAsk *ask; + GnomeKeyringAsk *other_ask; + enum AskType ask_type; +} GnomeKeyringPendingAsk; + +static gboolean +check_pending_ask (gpointer user_data) +{ + GnomeKeyringPendingAsk *pending_ask = user_data; + gboolean ready_to_check = FALSE; + GnomeKeyring *keyring; + + if (g_list_find (outstanding_asks, pending_ask->other_ask) != NULL) { + if (pending_ask->other_ask->ask_pid == 0) + ready_to_check = TRUE; + + if (pending_ask->other_ask->current_ask_type != pending_ask->ask_type) + ready_to_check = TRUE; + } else { + ready_to_check = TRUE; + } + + if (!ready_to_check) + return TRUE; + + if (pending_ask->ask->current_request->keyring != NULL) + keyring = pending_ask->ask->current_request->keyring; + else + keyring = pending_ask->ask->current_request->item->keyring; + + if (keyring->locked) { + launch_ask_helper (pending_ask->ask, pending_ask->ask_type); + } else { + /* keyring is unlocked, no need to do any asking */ + } + + gnome_keyring_ask_iterate (pending_ask->ask); + + g_free (pending_ask); + return FALSE; +} + +static gboolean +maybe_launch_ask_helper (GnomeKeyringAsk *ask, enum AskType ask_type) +{ + GnomeKeyring *keyring; + gboolean already_asking; + GList *l; + + if (ask->current_request->keyring != NULL) + keyring = ask->current_request->keyring; + else + keyring = ask->current_request->item->keyring; + + already_asking = FALSE; + + for (l = outstanding_asks; l != NULL; l = l->next) { + GnomeKeyringAsk *other_ask = l->data; + GnomeKeyring *other_keyring; + + if (other_ask == ask) + continue; + + if (other_ask->current_ask_type != ask_type) + continue; + + if (other_ask->current_request->keyring != NULL) + other_keyring = other_ask->current_request->keyring; + else + other_keyring = other_ask->current_request->item->keyring; + + if (keyring != other_keyring) + continue; + + if (other_ask->ask_pid != 0) { + GnomeKeyringPendingAsk *pending_ask = g_new0 (GnomeKeyringPendingAsk, 1); + + printf ("Another ask helper is already running: pid %d\n", other_ask->ask_pid); + + pending_ask->ask = ask; + pending_ask->other_ask = other_ask; + pending_ask->ask_type = ask_type; + g_timeout_add (200, check_pending_ask, pending_ask); + + return TRUE; + } + } + + return launch_ask_helper (ask, ask_type); +} + static void schedule_ask (GnomeKeyringAsk *ask) { @@ -2235,7 +2327,7 @@ schedule_ask (GnomeKeyringAsk *ask) request = ask->current_request; switch (request->request_type) { case GNOME_KEYRING_ACCESS_REQUEST_KEYRING: - if (!launch_ask_helper (ask, ASK_KEYRING_PASSWORD)) { + if (!maybe_launch_ask_helper (ask, ASK_KEYRING_PASSWORD)) { /* no way to allow request, denying */ ask->access_requests = g_list_remove (ask->access_requests, request); gnome_keyring_access_request_free (request); @@ -2245,7 +2337,7 @@ schedule_ask (GnomeKeyringAsk *ask) break; case GNOME_KEYRING_ACCESS_REQUEST_ITEM: if (request->item->keyring->locked) { - if (!launch_ask_helper (ask, ASK_KEYRING_PASSWORD)) { + if (!maybe_launch_ask_helper (ask, ASK_KEYRING_PASSWORD)) { /* no way to allow request, denying */ ask->access_requests = g_list_remove (ask->access_requests, request); gnome_keyring_access_request_free (request);