diff options
author | Daniel P. Berrange <berrange@redhat.com> | 2011-06-30 12:28:10 +0100 |
---|---|---|
committer | Daniel P. Berrange <berrange@redhat.com> | 2011-06-30 18:04:01 +0100 |
commit | df65adf13620db656baa3aa2a56819e6e09c1014 (patch) | |
tree | e73426bb0ffc1b375fbd6bc59f433c606188f5c5 | |
parent | Ensure RPC message is cleared before being reused (diff) | |
download | libvirt-df65adf13620db656baa3aa2a56819e6e09c1014.tar.gz libvirt-df65adf13620db656baa3aa2a56819e6e09c1014.tar.bz2 libvirt-df65adf13620db656baa3aa2a56819e6e09c1014.zip |
Fix release of filtered stream messages
The stream code was reusing a stream message object before
it was removed from the linked list of filtered messages.
This caused any later queued messages to be completely lost.
* daemon/stream.c: Delay reuse of stream message until
after it is removed from the queue
-rw-r--r-- | daemon/stream.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/daemon/stream.c b/daemon/stream.c index e4fcf90a1..685cee2e0 100644 --- a/daemon/stream.c +++ b/daemon/stream.c @@ -456,10 +456,6 @@ daemonStreamHandleWriteData(virNetServerClientPtr client, /* Partial write, so indicate we have more todo later */ if (msg->bufferOffset < msg->bufferLength) return 1; - - /* A dummy 'send' just to free up 'msg' object */ - memset(msg, 0, sizeof(*msg)); - return virNetServerClientSendMessage(client, msg); } else if (ret == -2) { /* Blocking, so indicate we have more todo later */ return 1; @@ -603,6 +599,22 @@ daemonStreamHandleWrite(virNetServerClientPtr client, virNetServerClientMarkClose(client); return -1; } + + /* 'CONTINUE' messages don't send a reply (unless error + * occurred), so to release the 'msg' object we need to + * send a fake zero-length reply. Nothing actually gets + * onto the wire, but this causes the client to reset + * its active request count / throttling + */ + if (msg->header.status == VIR_NET_CONTINUE) { + memset(msg, 0, sizeof(*msg)); + msg->header.type = VIR_NET_REPLY; + if (virNetServerClientSendMessage(client, msg) < 0) { + virNetMessageFree(msg); + virNetServerClientMarkClose(client); + return -1; + } + } } return 0; |