diff --git a/daemon/remote.c b/daemon/remote.c index 288990855e..a2e79efa99 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -483,11 +483,11 @@ cleanup: static int remoteDispatchClose(virNetServerPtr server ATTRIBUTE_UNUSED, - virNetServerClientPtr client, + virNetServerClientPtr client ATTRIBUTE_UNUSED, virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED, virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED) { - virNetServerClientClose(client); + virNetServerClientDelayedClose(client); return 0; } diff --git a/daemon/stream.c b/daemon/stream.c index 28f6c326d7..4a8f1eed91 100644 --- a/daemon/stream.c +++ b/daemon/stream.c @@ -338,7 +338,7 @@ int daemonFreeClientStream(virNetServerClientPtr client, memset(msg, 0, sizeof(*msg)); msg->header.type = VIR_NET_REPLY; if (virNetServerClientSendMessage(client, msg) < 0) { - virNetServerClientMarkClose(client); + virNetServerClientImmediateClose(client); virNetMessageFree(msg); ret = -1; } @@ -608,7 +608,7 @@ daemonStreamHandleWrite(virNetServerClientPtr client, virNetMessageQueueServe(&stream->rx); if (ret < 0) { virNetMessageFree(msg); - virNetServerClientMarkClose(client); + virNetServerClientImmediateClose(client); return -1; } @@ -623,7 +623,7 @@ daemonStreamHandleWrite(virNetServerClientPtr client, msg->header.type = VIR_NET_REPLY; if (virNetServerClientSendMessage(client, msg) < 0) { virNetMessageFree(msg); - virNetServerClientMarkClose(client); + virNetServerClientImmediateClose(client); return -1; } } diff --git a/src/rpc/virnetserverclient.c b/src/rpc/virnetserverclient.c index 6aeb3a4d4a..742c3a4bba 100644 --- a/src/rpc/virnetserverclient.c +++ b/src/rpc/virnetserverclient.c @@ -61,6 +61,7 @@ struct _virNetServerClient { int refs; bool wantClose; + bool delayedClose; virMutex lock; virNetSocketPtr sock; int auth; @@ -587,7 +588,14 @@ bool virNetServerClientIsClosed(virNetServerClientPtr client) return closed; } -void virNetServerClientMarkClose(virNetServerClientPtr client) +void virNetServerClientDelayedClose(virNetServerClientPtr client) +{ + virNetServerClientLock(client); + client->delayedClose = true; + virNetServerClientUnlock(client); +} + +void virNetServerClientImmediateClose(virNetServerClientPtr client) { virNetServerClientLock(client); client->wantClose = true; @@ -852,6 +860,9 @@ virNetServerClientDispatchWrite(virNetServerClientPtr client) virNetMessageFree(msg); virNetServerClientUpdateEvent(client); + + if (client->delayedClose) + client->wantClose = true; } } } diff --git a/src/rpc/virnetserverclient.h b/src/rpc/virnetserverclient.h index 66510c31c5..3d2e1fba45 100644 --- a/src/rpc/virnetserverclient.h +++ b/src/rpc/virnetserverclient.h @@ -86,9 +86,10 @@ void virNetServerClientSetDispatcher(virNetServerClientPtr client, virNetServerClientDispatchFunc func, void *opaque); void virNetServerClientClose(virNetServerClientPtr client); - bool virNetServerClientIsClosed(virNetServerClientPtr client); -void virNetServerClientMarkClose(virNetServerClientPtr client); + +void virNetServerClientDelayedClose(virNetServerClientPtr client); +void virNetServerClientImmediateClose(virNetServerClientPtr client); bool virNetServerClientWantClose(virNetServerClientPtr client); int virNetServerClientInit(virNetServerClientPtr client);