#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
static void virNetServerClientDispatchEvent(virNetSocketPtr sock, int events, void *opaque);
static void virNetServerClientUpdateEvent(virNetServerClientPtr client);
+static void virNetServerClientDispatchRead(virNetServerClientPtr client);
static void virNetServerClientLock(virNetServerClientPtr client)
{
mode = virNetServerClientCalculateHandleMode(client);
virNetSocketUpdateIOCallback(client->sock, mode);
+
+ if (client->rx && virNetSocketHasCachedData(client->sock))
+ virEventUpdateTimeout(client->sockTimer, 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,
int auth,
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);
#if HAVE_SASL
virNetSASLSessionFree(client->sasl);
#endif
+ if (client->sockTimer > 0)
+ virEventRemoveTimeout(client->sockTimer);
virNetTLSSessionFree(client->tls);
virNetTLSContextFree(client->tlsCtxt);
virNetSocketFree(client->sock);
} 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);
}
}