[Xcb-commit] 5 commits - xcb

Jamey Sharp jamey at kemper.freedesktop.org
Fri Sep 22 01:26:31 PDT 2006


 xcb/src/xcb.h      |   15 +++++++++++++
 xcb/src/xcb_conn.c |   29 +++++++++++++++++++++++---
 xcb/src/xcb_ext.c  |    4 +++
 xcb/src/xcb_in.c   |   58 +++++++++++++++++++++++++++++++++++++++++------------
 xcb/src/xcb_out.c  |   16 ++++++++++++++
 xcb/src/xcb_util.c |   10 +++++----
 xcb/src/xcb_xid.c  |    2 +
 xcb/src/xcb_xlib.c |    4 +++
 xcb/src/xcbint.h   |    3 ++
 9 files changed, 121 insertions(+), 20 deletions(-)

New commits:
diff-tree e2116cc271f39e7cfab8fadd07ef6b474ea2272a (from bd6ca8fb12980e33e132061217dd3e1ebb782caf)
Author: Jamey Sharp <jamey at minilop.net>
Date:   Fri Sep 15 01:51:05 2006 -0700

    Shut down the connection in all "fatal" error cases.

diff --git a/xcb/src/xcb_conn.c b/xcb/src/xcb_conn.c
index 29d91f4..de1f6e4 100644
--- a/xcb/src/xcb_conn.c
+++ b/xcb/src/xcb_conn.c
@@ -156,7 +156,10 @@ static int write_vec(XCBConnection *c, s
     if(n < 0 && errno == EAGAIN)
         return 1;
     if(n <= 0)
+    {
+        _xcb_conn_shutdown(c);
         return 0;
+    }
 
     for(; *count; --*count, ++*vector)
     {
@@ -280,7 +283,10 @@ int _xcb_conn_wait(XCBConnection *c, pth
 	ret = select(c->fd + 1, &rfds, &wfds, 0, 0);
     } while (ret == -1 && errno == EINTR);
     if (ret < 0)
+    {
+        _xcb_conn_shutdown(c);
 	ret = 0;
+    }
     pthread_mutex_lock(&c->iolock);
 
     if(ret)
diff --git a/xcb/src/xcb_in.c b/xcb/src/xcb_in.c
index d8b608a..2ac1e52 100644
--- a/xcb/src/xcb_in.c
+++ b/xcb/src/xcb_in.c
@@ -142,7 +142,10 @@ static int read_packet(XCBConnection *c)
 
     buf = malloc(length + (genrep.response_type == XCBReply ? 0 : sizeof(CARD32)));
     if(!buf)
+    {
+        _xcb_conn_shutdown(c);
         return 0;
+    }
     if(_xcb_in_read_block(c, buf, length) <= 0)
     {
         free(buf);
@@ -164,7 +167,10 @@ static int read_packet(XCBConnection *c)
         reader_list *reader;
         struct reply_list *cur = malloc(sizeof(struct reply_list));
         if(!cur)
+        {
+            _xcb_conn_shutdown(c);
             return 0;
+        }
         cur->reply = buf;
         cur->next = 0;
         *c->in.current_reply_tail = cur;
@@ -187,6 +193,7 @@ static int read_packet(XCBConnection *c)
     event = malloc(sizeof(struct event_list));
     if(!event)
     {
+        _xcb_conn_shutdown(c);
         free(buf);
         return 0;
     }
@@ -486,7 +493,10 @@ int _xcb_in_expect_reply(XCBConnection *
     pending_reply *pend = malloc(sizeof(pending_reply));
     assert(workaround != WORKAROUND_NONE || flags != 0);
     if(!pend)
+    {
+        _xcb_conn_shutdown(c);
         return 0;
+    }
     pend->request = request;
     pend->workaround = workaround;
     pend->flags = flags;
@@ -503,7 +513,10 @@ int _xcb_in_read(XCBConnection *c)
         c->in.queue_len += n;
     while(read_packet(c))
         /* empty */;
-    return (n > 0) || (n < 0 && errno == EAGAIN);
+    if((n > 0) || (n < 0 && errno == EAGAIN))
+        return 1;
+    _xcb_conn_shutdown(c);
+    return 0;
 }
 
 int _xcb_in_read_block(XCBConnection *c, void *buf, int len)
@@ -520,7 +533,10 @@ int _xcb_in_read_block(XCBConnection *c,
     {
         int ret = read_block(c->fd, (char *) buf + done, len - done);
         if(ret <= 0)
+        {
+            _xcb_conn_shutdown(c);
             return ret;
+        }
     }
 
     return len;
diff --git a/xcb/src/xcb_out.c b/xcb/src/xcb_out.c
index 91f7ea1..1b68215 100644
--- a/xcb/src/xcb_out.c
+++ b/xcb/src/xcb_out.c
@@ -112,7 +112,10 @@ unsigned int XCBSendRequest(XCBConnectio
         {
             const XCBQueryExtensionRep *extension = XCBGetExtensionData(c, req->ext);
             if(!(extension && extension->present))
+            {
+                _xcb_conn_shutdown(c);
                 return 0;
+            }
             ((CARD8 *) vector[0].iov_base)[0] = extension->major_opcode;
             ((CARD8 *) vector[0].iov_base)[1] = req->opcode;
         }
@@ -139,7 +142,10 @@ unsigned int XCBSendRequest(XCBConnectio
             longlen = 0;
         }
         else if(longlen > XCBGetMaximumRequestLength(c))
+        {
+            _xcb_conn_shutdown(c);
             return 0; /* server can't take this; maybe need BIGREQUESTS? */
+        }
 
         /* set the length field. */
         ((CARD16 *) vector[0].iov_base)[1] = shortlen;
@@ -197,7 +203,10 @@ unsigned int XCBSendRequest(XCBConnectio
     }
 
     if(!write_block(c, vector, veclen))
+    {
+        _xcb_conn_shutdown(c);
         request = 0;
+    }
     pthread_mutex_unlock(&c->iolock);
     return request;
 }
diff-tree bd6ca8fb12980e33e132061217dd3e1ebb782caf (from 4d58509b7a15aabf1185eda82ab96c25b3418731)
Author: Jamey Sharp <jamey at minilop.net>
Date:   Fri Sep 15 01:57:53 2006 -0700

    Add a private connection shutdown method for error cases.

diff --git a/xcb/src/xcb_conn.c b/xcb/src/xcb_conn.c
index 2b24dc0..29d91f4 100644
--- a/xcb/src/xcb_conn.c
+++ b/xcb/src/xcb_conn.c
@@ -247,6 +247,11 @@ void XCBDisconnect(XCBConnection *c)
 
 /* Private interface */
 
+void _xcb_conn_shutdown(XCBConnection *c)
+{
+    c->has_error = 1;
+}
+
 int _xcb_conn_wait(XCBConnection *c, pthread_cond_t *cond, struct iovec **vector, int *count)
 {
     int ret;
diff --git a/xcb/src/xcbint.h b/xcb/src/xcbint.h
index f059522..01d8a20 100644
--- a/xcb/src/xcbint.h
+++ b/xcb/src/xcbint.h
@@ -158,6 +158,7 @@ struct XCBConnection {
     _xcb_xid xid;
 };
 
+void _xcb_conn_shutdown(XCBConnection *c);
 int _xcb_conn_wait(XCBConnection *c, pthread_cond_t *cond, struct iovec **vector, int *count);
 
 
diff-tree 4d58509b7a15aabf1185eda82ab96c25b3418731 (from 8c82c79540a5b6ad3df68b3f961d53186a17a651)
Author: Jamey Sharp <jamey at minilop.net>
Date:   Fri Sep 15 01:09:27 2006 -0700

    Make all public functions do nothing on an error connection.

diff --git a/xcb/src/xcb_conn.c b/xcb/src/xcb_conn.c
index 0176524..2b24dc0 100644
--- a/xcb/src/xcb_conn.c
+++ b/xcb/src/xcb_conn.c
@@ -179,12 +179,16 @@ static int write_vec(XCBConnection *c, s
 
 const XCBSetup *XCBGetSetup(XCBConnection *c)
 {
+    if(c->has_error)
+        return 0;
     /* doesn't need locking because it's never written to. */
     return c->setup;
 }
 
 int XCBGetFileDescriptor(XCBConnection *c)
 {
+    if(c->has_error)
+        return -1;
     /* doesn't need locking because it's never written to. */
     return c->fd;
 }
@@ -225,7 +229,7 @@ XCBConnection *XCBConnectToFD(int fd, XC
 
 void XCBDisconnect(XCBConnection *c)
 {
-    if(!c)
+    if(c->has_error)
         return;
 
     free(c->setup);
diff --git a/xcb/src/xcb_ext.c b/xcb/src/xcb_ext.c
index 610ec57..3732515 100644
--- a/xcb/src/xcb_ext.c
+++ b/xcb/src/xcb_ext.c
@@ -84,6 +84,8 @@ static lazyreply *get_lazyreply(XCBConne
 const XCBQueryExtensionRep *XCBGetExtensionData(XCBConnection *c, XCBExtension *ext)
 {
     lazyreply *data;
+    if(c->has_error)
+        return 0;
 
     pthread_mutex_lock(&c->ext.lock);
     data = get_lazyreply(c, ext);
@@ -99,6 +101,8 @@ const XCBQueryExtensionRep *XCBGetExtens
 
 void XCBPrefetchExtensionData(XCBConnection *c, XCBExtension *ext)
 {
+    if(c->has_error)
+        return;
     pthread_mutex_lock(&c->ext.lock);
     get_lazyreply(c, ext);
     pthread_mutex_unlock(&c->ext.lock);
diff --git a/xcb/src/xcb_in.c b/xcb/src/xcb_in.c
index eab8b1d..d8b608a 100644
--- a/xcb/src/xcb_in.c
+++ b/xcb/src/xcb_in.c
@@ -308,6 +308,8 @@ void *XCBWaitForReply(XCBConnection *c, 
     void *ret = 0;
     if(e)
         *e = 0;
+    if(c->has_error)
+        return 0;
 
     pthread_mutex_lock(&c->iolock);
 
@@ -356,6 +358,13 @@ void *XCBWaitForReply(XCBConnection *c, 
 int XCBPollForReply(XCBConnection *c, unsigned int request, void **reply, XCBGenericError **error)
 {
     int ret;
+    if(c->has_error)
+    {
+        *reply = 0;
+        if(error)
+            *error = 0;
+        return 1; /* would not block */
+    }
     assert(reply != 0);
     pthread_mutex_lock(&c->iolock);
     ret = poll_for_reply(c, request, reply, error);
@@ -366,6 +375,8 @@ int XCBPollForReply(XCBConnection *c, un
 XCBGenericEvent *XCBWaitForEvent(XCBConnection *c)
 {
     XCBGenericEvent *ret;
+    if(c->has_error)
+        return 0;
     pthread_mutex_lock(&c->iolock);
     /* get_event returns 0 on empty list. */
     while(!(ret = get_event(c)))
@@ -379,19 +390,22 @@ XCBGenericEvent *XCBWaitForEvent(XCBConn
 
 XCBGenericEvent *XCBPollForEvent(XCBConnection *c, int *error)
 {
-    XCBGenericEvent *ret = 0;
-    int success;
-    pthread_mutex_lock(&c->iolock);
-    /* FIXME: follow X meets Z architecture changes. */
-    success = _xcb_in_read(c);
-    if(success)
-        ret = get_event(c);
-    pthread_mutex_unlock(&c->iolock);
-    if(success)
+    if(!c->has_error)
     {
-        if(error)
-            *error = 0;
-        return ret;
+        XCBGenericEvent *ret = 0;
+        int success;
+        pthread_mutex_lock(&c->iolock);
+        /* FIXME: follow X meets Z architecture changes. */
+        success = _xcb_in_read(c);
+        if(success)
+            ret = get_event(c);
+        pthread_mutex_unlock(&c->iolock);
+        if(success)
+        {
+            if(error)
+                *error = 0;
+            return ret;
+        }
     }
     if(error)
         *error = -1;
@@ -410,6 +424,8 @@ XCBGenericError *XCBRequestCheck(XCBConn
      * XCBGetInputFocusReply, and XCBWaitForReply. */
     XCBGenericError *ret;
     void *reply;
+    if(c->has_error)
+        return 0;
     if(XCB_SEQUENCE_COMPARE(cookie.sequence,>,c->in.request_expected)
        && XCB_SEQUENCE_COMPARE(cookie.sequence,>,c->in.request_completed))
     {
diff --git a/xcb/src/xcb_out.c b/xcb/src/xcb_out.c
index 56e02f7..91f7ea1 100644
--- a/xcb/src/xcb_out.c
+++ b/xcb/src/xcb_out.c
@@ -59,6 +59,8 @@ static int write_block(XCBConnection *c,
 
 CARD32 XCBGetMaximumRequestLength(XCBConnection *c)
 {
+    if(c->has_error)
+        return 0;
     pthread_mutex_lock(&c->out.reqlenlock);
     if(!c->out.maximum_request_length)
     {
@@ -91,6 +93,9 @@ unsigned int XCBSendRequest(XCBConnectio
     int veclen = req->count;
     enum workarounds workaround = WORKAROUND_NONE;
 
+    if(c->has_error)
+        return 0;
+
     assert(c != 0);
     assert(vector != 0);
     assert(req->count > 0);
@@ -200,6 +205,8 @@ unsigned int XCBSendRequest(XCBConnectio
 int XCBFlush(XCBConnection *c)
 {
     int ret;
+    if(c->has_error)
+        return 0;
     pthread_mutex_lock(&c->iolock);
     ret = _xcb_out_flush_to(c, c->out.request);
     pthread_mutex_unlock(&c->iolock);
diff --git a/xcb/src/xcb_xid.c b/xcb/src/xcb_xid.c
index 1c53b53..a2e7dec 100644
--- a/xcb/src/xcb_xid.c
+++ b/xcb/src/xcb_xid.c
@@ -36,6 +36,8 @@
 CARD32 XCBGenerateID(XCBConnection *c)
 {
     CARD32 ret;
+    if(c->has_error)
+        return -1;
     pthread_mutex_lock(&c->xid.lock);
     if(c->xid.last == c->xid.max)
     {
diff --git a/xcb/src/xcb_xlib.c b/xcb/src/xcb_xlib.c
index 61518f7..054bc2e 100644
--- a/xcb/src/xcb_xlib.c
+++ b/xcb/src/xcb_xlib.c
@@ -28,10 +28,14 @@
 
 unsigned int XCBGetRequestSent(XCBConnection *c)
 {
+    if(c->has_error)
+        return 0;
     return c->out.request;
 }
 
 pthread_mutex_t *XCBGetIOLock(XCBConnection *c)
 {
+    if(c->has_error)
+        return 0;
     return &c->iolock;
 }
diff-tree 8c82c79540a5b6ad3df68b3f961d53186a17a651 (from 29fa28a9328938f9b9cbc200910ad7f0d941cc10)
Author: Jamey Sharp <jamey at minilop.net>
Date:   Fri Sep 15 00:39:51 2006 -0700

    Convert connection functions to return error objects.

diff --git a/xcb/src/xcb_conn.c b/xcb/src/xcb_conn.c
index b0d727b..0176524 100644
--- a/xcb/src/xcb_conn.c
+++ b/xcb/src/xcb_conn.c
@@ -44,6 +44,8 @@ typedef struct {
     CARD16 length;
 } XCBSetupGeneric;
 
+static const int error_connection = 1;
+
 static int set_fd_flags(const int fd)
 {
     long flags = fcntl(fd, F_GETFL, 0);
@@ -199,7 +201,7 @@ XCBConnection *XCBConnectToFD(int fd, XC
 
     c = calloc(1, sizeof(XCBConnection));
     if(!c)
-        return 0;
+        return (XCBConnection *) &error_connection;
 
     c->fd = fd;
 
@@ -215,7 +217,7 @@ XCBConnection *XCBConnectToFD(int fd, XC
         ))
     {
         XCBDisconnect(c);
-        return 0;
+        return (XCBConnection *) &error_connection;
     }
 
     return c;
diff --git a/xcb/src/xcb_util.c b/xcb/src/xcb_util.c
index 3bdcd36..d93353b 100644
--- a/xcb/src/xcb_util.c
+++ b/xcb/src/xcb_util.c
@@ -45,6 +45,8 @@
 #include "xcbext.h"
 #include "xcbint.h"
 
+static const int error_connection = 1;
+
 int XCBPopcount(CARD32 mask)
 {
     unsigned long y;
@@ -212,11 +214,11 @@ XCBConnection *XCBConnect(const char *di
     XCBAuthInfo auth;
 
     if(!XCBParseDisplay(displayname, &host, &display, screenp))
-        return 0;
+        return (XCBConnection *) &error_connection;
     fd = _xcb_open(host, display);
     free(host);
     if(fd == -1)
-        return 0;
+        return (XCBConnection *) &error_connection;
 
     _xcb_get_auth_info(fd, &auth);
     c = XCBConnectToFD(fd, &auth);
@@ -231,11 +233,11 @@ XCBConnection *XCBConnectToDisplayWithAu
     char *host;
 
     if(!XCBParseDisplay(displayname, &host, &display, screenp))
-        return 0;
+        return (XCBConnection *) &error_connection;
     fd = _xcb_open(host, display);
     free(host);
     if(fd == -1)
-        return 0;
+        return (XCBConnection *) &error_connection;
 
     return XCBConnectToFD(fd, auth);
 }
diff-tree 29fa28a9328938f9b9cbc200910ad7f0d941cc10 (from 184e7a4c56db40e5b87c4c47f963f20519db2e1e)
Author: Jamey Sharp <jamey at minilop.net>
Date:   Fri Sep 15 00:29:39 2006 -0700

    Provide a "has error" property for XCBConnection.

diff --git a/xcb/src/xcb.h b/xcb/src/xcb.h
index 114f2cf..3d193e1 100644
--- a/xcb/src/xcb.h
+++ b/xcb/src/xcb.h
@@ -334,6 +334,21 @@ const XCBSetup *XCBGetSetup(XCBConnectio
 int XCBGetFileDescriptor(XCBConnection *c);
 
 /**
+ * @brief Test whether the connection has shut down due to a fatal error.
+ * @param c: The connection.
+ * @return 1 if the connection is in an error state; 0 otherwise.
+ *
+ * Some errors that occur in the context of an XCBConnection
+ * are unrecoverable. When such an error occurs, the
+ * connection is shut down and further operations on the
+ * XCBConnection have no effect.
+ *
+ * @todo Other functions should document the conditions in
+ * which they shut down the connection.
+ */
+int XCBConnectionHasError(XCBConnection *c);
+
+/**
  * @brief Connects to the X server.
  * @param fd: The file descriptor.
  * @param auth_info: Authentication data.
diff --git a/xcb/src/xcb_conn.c b/xcb/src/xcb_conn.c
index be80bac..b0d727b 100644
--- a/xcb/src/xcb_conn.c
+++ b/xcb/src/xcb_conn.c
@@ -187,6 +187,12 @@ int XCBGetFileDescriptor(XCBConnection *
     return c->fd;
 }
 
+int XCBConnectionHasError(XCBConnection *c)
+{
+    /* doesn't need locking because it's read and written atomically. */
+    return c->has_error;
+}
+
 XCBConnection *XCBConnectToFD(int fd, XCBAuthInfo *auth_info)
 {
     XCBConnection* c;
diff --git a/xcb/src/xcbint.h b/xcb/src/xcbint.h
index 9048e9d..f059522 100644
--- a/xcb/src/xcbint.h
+++ b/xcb/src/xcbint.h
@@ -142,6 +142,8 @@ void _xcb_ext_destroy(XCBConnection *c);
 /* xcb_conn.c */
 
 struct XCBConnection {
+    int has_error;
+
     /* constant data */
     XCBSetup *setup;
     int fd;


More information about the xcb-commit mailing list