[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