mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-25 15:15:25 +00:00
ServerClient: Flush cached data
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.
This commit is contained in:
parent
c85013b90d
commit
b7b5e0c833
@ -72,6 +72,8 @@ struct _virNetServerClient
|
|||||||
#if HAVE_SASL
|
#if HAVE_SASL
|
||||||
virNetSASLSessionPtr sasl;
|
virNetSASLSessionPtr sasl;
|
||||||
#endif
|
#endif
|
||||||
|
int sockTimer; /* Timer to be fired upon cached data,
|
||||||
|
* so we jump out from poll() immediately */
|
||||||
|
|
||||||
/* Count of messages in the 'tx' queue,
|
/* Count of messages in the 'tx' queue,
|
||||||
* and the server worker pool queue
|
* and the server worker pool queue
|
||||||
@ -103,6 +105,7 @@ struct _virNetServerClient
|
|||||||
|
|
||||||
static void virNetServerClientDispatchEvent(virNetSocketPtr sock, int events, void *opaque);
|
static void virNetServerClientDispatchEvent(virNetSocketPtr sock, int events, void *opaque);
|
||||||
static void virNetServerClientUpdateEvent(virNetServerClientPtr client);
|
static void virNetServerClientUpdateEvent(virNetServerClientPtr client);
|
||||||
|
static void virNetServerClientDispatchRead(virNetServerClientPtr client);
|
||||||
|
|
||||||
static void virNetServerClientLock(virNetServerClientPtr client)
|
static void virNetServerClientLock(virNetServerClientPtr client)
|
||||||
{
|
{
|
||||||
@ -204,6 +207,9 @@ static void virNetServerClientUpdateEvent(virNetServerClientPtr client)
|
|||||||
mode = virNetServerClientCalculateHandleMode(client);
|
mode = virNetServerClientCalculateHandleMode(client);
|
||||||
|
|
||||||
virNetSocketUpdateIOCallback(client->sock, mode);
|
virNetSocketUpdateIOCallback(client->sock, mode);
|
||||||
|
|
||||||
|
if (client->rx && virNetSocketHasCachedData(client->sock))
|
||||||
|
virEventUpdateTimeout(client->sockTimer, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -293,6 +299,19 @@ virNetServerClientCheckAccess(virNetServerClientPtr client)
|
|||||||
return 0;
|
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,
|
virNetServerClientPtr virNetServerClientNew(virNetSocketPtr sock,
|
||||||
int auth,
|
int auth,
|
||||||
@ -319,6 +338,11 @@ virNetServerClientPtr virNetServerClientNew(virNetSocketPtr sock,
|
|||||||
client->tlsCtxt = tls;
|
client->tlsCtxt = tls;
|
||||||
client->nrequests_max = nrequests_max;
|
client->nrequests_max = nrequests_max;
|
||||||
|
|
||||||
|
client->sockTimer = virEventAddTimeout(-1, virNetServerClientSockTimerFunc,
|
||||||
|
client, NULL);
|
||||||
|
if (client->sockTimer < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
if (tls)
|
if (tls)
|
||||||
virNetTLSContextRef(tls);
|
virNetTLSContextRef(tls);
|
||||||
|
|
||||||
@ -557,6 +581,8 @@ void virNetServerClientFree(virNetServerClientPtr client)
|
|||||||
#if HAVE_SASL
|
#if HAVE_SASL
|
||||||
virNetSASLSessionFree(client->sasl);
|
virNetSASLSessionFree(client->sasl);
|
||||||
#endif
|
#endif
|
||||||
|
if (client->sockTimer > 0)
|
||||||
|
virEventRemoveTimeout(client->sockTimer);
|
||||||
virNetTLSSessionFree(client->tls);
|
virNetTLSSessionFree(client->tls);
|
||||||
virNetTLSContextFree(client->tlsCtxt);
|
virNetTLSContextFree(client->tlsCtxt);
|
||||||
virNetSocketFree(client->sock);
|
virNetSocketFree(client->sock);
|
||||||
@ -990,7 +1016,8 @@ virNetServerClientDispatchEvent(virNetSocketPtr sock, int events, void *opaque)
|
|||||||
} else {
|
} else {
|
||||||
if (events & VIR_EVENT_HANDLE_WRITABLE)
|
if (events & VIR_EVENT_HANDLE_WRITABLE)
|
||||||
virNetServerClientDispatchWrite(client);
|
virNetServerClientDispatchWrite(client);
|
||||||
if (events & VIR_EVENT_HANDLE_READABLE)
|
if (events & VIR_EVENT_HANDLE_READABLE &&
|
||||||
|
client->rx)
|
||||||
virNetServerClientDispatchRead(client);
|
virNetServerClientDispatchRead(client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user