summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2010-06-30 07:59:04 -0700
committerKeith Packard <keithp@keithp.com>2010-06-30 07:59:04 -0700
commit28e33ae6f69f716ece5d68e63fc52557236c5f6e (patch)
tree9543ef519cac20b6e1c66ac2fbe1ea047e7edb0e
parent018c878e9495b21146c8f38617fdd1bf6d8cc73b (diff)
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 <keithp@keithp.com> Reviewed-by: Daniel Stone <daniel@fooishbar.org> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r--include/dixstruct.h1
-rw-r--r--os/connection.c9
2 files changed, 10 insertions, 0 deletions
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))
{