[libvirt] [PATCH v2] ServerClient: Flush cached data
Daniel P. Berrange
berrange at redhat.com
Tue Nov 1 14:49:46 UTC 2011
On Tue, Nov 01, 2011 at 03:46:06PM +0100, Jiri Denemark wrote:
> From: Michal Privoznik <mprivozn at redhat.com>
>
> If daemon is using SASL it reads client data into a cache. This cache is
> big (usually 65KB) and can thus contain 2 or more messages. However,
> on socket event we can dispatch only one message. So if we read two
> messages at once, the second will not be dispatched as the socket event
> goes away with filling the cache.
> Moreover, when dispatching the cache we need to remember to take care
> of client max requests limit.
> ---
> src/rpc/virnetserverclient.c | 29 ++++++++++++++++++++++++++++-
> 1 files changed, 28 insertions(+), 1 deletions(-)
>
> diff --git a/src/rpc/virnetserverclient.c b/src/rpc/virnetserverclient.c
> index 1256f0f..2f5ae8f 100644
> --- a/src/rpc/virnetserverclient.c
> +++ b/src/rpc/virnetserverclient.c
> @@ -72,6 +72,8 @@ struct _virNetServerClient
> #if HAVE_SASL
> virNetSASLSessionPtr sasl;
> #endif
> + int sockTimer; /* Timer to be fired upon cached data,
> + * so we jump out from poll() immediately */
>
> /* Count of messages in the 'tx' queue,
> * and the server worker pool queue
> @@ -103,6 +105,7 @@ struct _virNetServerClient
>
> static void virNetServerClientDispatchEvent(virNetSocketPtr sock, int events, void *opaque);
> static void virNetServerClientUpdateEvent(virNetServerClientPtr client);
> +static void virNetServerClientDispatchRead(virNetServerClientPtr client);
>
> static void virNetServerClientLock(virNetServerClientPtr client)
> {
> @@ -204,6 +207,9 @@ static void virNetServerClientUpdateEvent(virNetServerClientPtr client)
> mode = virNetServerClientCalculateHandleMode(client);
>
> virNetSocketUpdateIOCallback(client->sock, mode);
> +
> + if (client->rx && virNetSocketHasCachedData(client->sock))
> + virEventUpdateTimeout(client->sockTimer, 0);
> }
>
>
> @@ -293,6 +299,19 @@ virNetServerClientCheckAccess(virNetServerClientPtr client)
> return 0;
> }
>
> +static void virNetServerClientSockTimerFunc(int timer,
> + void *opaque)
> +{
> + virNetServerClientPtr client = opaque;
> + virNetServerClientLock(client);
> + virEventUpdateTimeout(timer, -1);
> + /* Although client->rx != NULL when this timer is enabled, it might have
> + * changed since the client was unlocked in the meantime. */
> + if (client->rx)
> + virNetServerClientDispatchRead(client);
> + virNetServerClientUnlock(client);
> +}
> +
>
> virNetServerClientPtr virNetServerClientNew(virNetSocketPtr sock,
> int auth,
> @@ -319,6 +338,11 @@ virNetServerClientPtr virNetServerClientNew(virNetSocketPtr sock,
> client->tlsCtxt = tls;
> client->nrequests_max = nrequests_max;
>
> + client->sockTimer = virEventAddTimeout(-1, virNetServerClientSockTimerFunc,
> + client, NULL);
> + if (client->sockTimer < 0)
> + goto error;
> +
> if (tls)
> virNetTLSContextRef(tls);
>
> @@ -557,6 +581,8 @@ void virNetServerClientFree(virNetServerClientPtr client)
> #if HAVE_SASL
> virNetSASLSessionFree(client->sasl);
> #endif
> + if (client->sockTimer > 0)
> + virEventRemoveTimeout(client->sockTimer);
> virNetTLSSessionFree(client->tls);
> virNetTLSContextFree(client->tlsCtxt);
> virNetSocketFree(client->sock);
> @@ -990,7 +1016,8 @@ virNetServerClientDispatchEvent(virNetSocketPtr sock, int events, void *opaque)
> } else {
> if (events & VIR_EVENT_HANDLE_WRITABLE)
> virNetServerClientDispatchWrite(client);
> - if (events & VIR_EVENT_HANDLE_READABLE)
> + if (events & VIR_EVENT_HANDLE_READABLE &&
> + client->rx)
> virNetServerClientDispatchRead(client);
> }
> }
ACK this looks good
Daniel
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
More information about the libvir-list
mailing list