mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-23 22:25:25 +00:00
rpc: Fix deadlock if there is no worker pool available
@srv must be unlocked for the call virNetServerProcessMsg otherwise a deadlock can occur. Since the pointer 'srv->workers' will never be changed after initialization and the thread pool has it's own locking we can release the lock of 'srv' earlier. This also fixes the deadlock. Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com> Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com> Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com> Reviewed-by: John Ferlan <jferlan@redhat.com>
This commit is contained in:
parent
80250f70c5
commit
45e00c7f2d
@ -51,6 +51,7 @@ struct _virNetServer {
|
||||
|
||||
char *name;
|
||||
|
||||
/* Immutable pointer, self-locking APIs */
|
||||
virThreadPoolPtr workers;
|
||||
|
||||
char *mdnsGroupName;
|
||||
@ -177,9 +178,11 @@ static void virNetServerHandleJob(void *jobOpaque, void *opaque)
|
||||
VIR_FREE(job);
|
||||
}
|
||||
|
||||
static void virNetServerDispatchNewMessage(virNetServerClientPtr client,
|
||||
virNetMessagePtr msg,
|
||||
void *opaque)
|
||||
|
||||
static void
|
||||
virNetServerDispatchNewMessage(virNetServerClientPtr client,
|
||||
virNetMessagePtr msg,
|
||||
void *opaque)
|
||||
{
|
||||
virNetServerPtr srv = opaque;
|
||||
virNetServerProgramPtr prog = NULL;
|
||||
@ -196,6 +199,11 @@ static void virNetServerDispatchNewMessage(virNetServerClientPtr client,
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* we can unlock @srv since @prog can only become invalid in case
|
||||
* of disposing @srv, but let's grab a ref first to ensure nothing
|
||||
* disposes of it before we use it. */
|
||||
virObjectRef(srv);
|
||||
virObjectUnlock(srv);
|
||||
|
||||
if (srv->workers) {
|
||||
virNetServerJobPtr job;
|
||||
@ -223,15 +231,16 @@ static void virNetServerDispatchNewMessage(virNetServerClientPtr client,
|
||||
goto error;
|
||||
}
|
||||
|
||||
virObjectUnlock(srv);
|
||||
virObjectUnref(srv);
|
||||
return;
|
||||
|
||||
error:
|
||||
virNetMessageFree(msg);
|
||||
virNetServerClientClose(client);
|
||||
virObjectUnlock(srv);
|
||||
virObjectUnref(srv);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* virNetServerCheckLimits:
|
||||
* @srv: server to check limits on
|
||||
|
Loading…
Reference in New Issue
Block a user