From 28e33ae6f69f716ece5d68e63fc52557236c5f6e Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 30 Jun 2010 07:59:04 -0700 Subject: [PATCH] OS support: fix writeable client vs IgnoreClient behavior When ResetCurrentRequest is called, or IgnoreClient is called when a client has input pending, IgnoredClientsWithInput will be set. However, a subsequent IgnoreClient request will clear the client fd from that fd set, potentially causing the client to hang. So add an Ignore/Attend count, and only apply the ignore logic on the first ignore and the attend logic on the last attend. This is consistent with the comments for these functions; callers must pair them. Fixes https://bugs.freedesktop.org/show_bug.cgi?id=27035. Reviewed-by: Keith Packard Reviewed-by: Daniel Stone Signed-off-by: Jesse Barnes Signed-off-by: Keith Packard --- include/dixstruct.h | 1 + os/connection.c | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/include/dixstruct.h b/include/dixstruct.h index 96104275d..efa2577f8 100644 --- a/include/dixstruct.h +++ b/include/dixstruct.h @@ -98,6 +98,7 @@ typedef struct _Client { int clientGone; int noClientException; /* this client died or needs to be * killed */ + int ignoreCount; /* count for Attend/IgnoreClient */ SaveSetElt *saveSet; int numSaved; int (**requestVector) ( diff --git a/os/connection.c b/os/connection.c index cd0ca5efc..c143fb6d3 100644 --- a/os/connection.c +++ b/os/connection.c @@ -1147,6 +1147,10 @@ IgnoreClient (ClientPtr client) OsCommPtr oc = (OsCommPtr)client->osPrivate; int connection = oc->fd; + client->ignoreCount++; + if (client->ignoreCount > 1) + return; + isItTimeToYield = TRUE; if (!GrabInProgress || FD_ISSET(connection, &AllClients)) { @@ -1181,6 +1185,11 @@ AttendClient (ClientPtr client) { OsCommPtr oc = (OsCommPtr)client->osPrivate; int connection = oc->fd; + + client->ignoreCount--; + if (client->ignoreCount) + return; + if (!GrabInProgress || GrabInProgress == client->index || FD_ISSET(connection, &GrabImperviousClients)) {