[libvirt] [PATCH] client: Check if other thread claims it has the buck before claiming it.
Jiri Denemark
jdenemar at redhat.com
Fri Dec 2 13:21:55 UTC 2011
On Fri, Dec 02, 2011 at 14:06:06 +0100, Peter Krempa wrote:
> Originaly, the code checked if another client is the queue and infered
> ownership of the buck from that. Commit fa9595003d043df9f2efe95521c008
> added a separate variable to track the buck. That caused, that a new
> call might enter claiming it has the buck, while another thread was
> signalled to take the buck. This ends in two threads claiming they hold
> the buck and entering poll(). This happens due to a race on waking up
> threads on the client lock mutex.
>
> This caused multi-threaded clients to hang, most prominently visible and
> reproducible on python based clients, like virt-manager.
>
> This patch causes threads, that have been signalled to take the buck to
> re-check if buck is held by another thread.
> ---
> src/rpc/virnetclient.c | 9 ++++++++-
> 1 files changed, 8 insertions(+), 1 deletions(-)
>
> diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
> index 5165c8d..07d8a60 100644
> --- a/src/rpc/virnetclient.c
> +++ b/src/rpc/virnetclient.c
> @@ -1545,6 +1545,7 @@ static int virNetClientIO(virNetClientPtr client,
> virNetClientCallQueue(&client->waitDispatch, thiscall);
>
> /* Check to see if another thread is dispatching */
> +recheck:
> if (client->haveTheBuck) {
> char ignore = 1;
>
> @@ -1592,7 +1593,13 @@ static int virNetClientIO(virNetClientPtr client,
> goto cleanup;
> }
>
> - /* Grr, someone passed the buck onto us ... */
> + /* Grr, someone might have passed the buck onto us ... */
> +
> + /* We need to re-check if the buck has been passed to this thread
> + * as this thread might have been signalled to wake up, but the another
Just remove "the" from "but the another".
> + * call might acquire the lock before this thread manages to wake up.
> + * This could cause that two threads claim they have the buck */
> + goto recheck;
> }
>
> VIR_DEBUG("We have the buck %p %p", client->waitDispatch, thiscall);
ACK
Jirka
More information about the libvir-list
mailing list