--- gnupg-2.0.10.orig/agent/command.c 2008-12-10 14:51:28 +0300 +++ gnupg-2.0.10.orig/agent/command.c 2009-03-03 14:21:43 +0300 @@ -918,8 +918,36 @@ if (!strcmp (desc, "X")) desc = NULL; +retry: pw = cacheid ? agent_get_cache (cacheid, CACHE_MODE_NORMAL, &cache_marker) : NULL; + if (!pw) + { + + /* If the pinentry is currently in use, we wait up to 60 seconds + for it to close and check the cache again. This solves a common + situation where several requests for unprotecting a key have + been made but the user is still entering the passphrase for + the first request. Because all requests to agent_askpin are + serialized they would then pop up one after the other to + request the passphrase - despite that the user has already + entered it and is then available in the cache. This + implementation is not race free but in the worst case the + user has to enter the passphrase only once more. */ + if (pinentry_active_p (ctrl, 0)) + { + /* Active - wait */ + if (!pinentry_active_p (ctrl, 60)) + { + /* We need to give the other thread a chance to actually put + it into the cache. */ + pth_sleep (1); + goto retry; + } + /* Timeout - better call pinentry now the plain way. */ + } + } + if (pw) { rc = send_back_passphrase (ctx, opt_data, pw);