[Xcb] [PATCH 3/4] xcb_connect*: cancel thread immediately during connect()
Rémi Denis-Courmont
remi at remlab.net
Thu Jan 7 09:25:14 PST 2010
---
src/xcb_util.c | 54 +++++++++++++++++++++---------------------------------
1 files changed, 21 insertions(+), 33 deletions(-)
diff --git a/src/xcb_util.c b/src/xcb_util.c
index 3b6fcea..64049d1 100644
--- a/src/xcb_util.c
+++ b/src/xcb_util.c
@@ -125,6 +125,16 @@ static void cleanup_file(void *data)
close((intptr_t)data);
}
+static int _xcb_connect_safe(int fd, const struct sockaddr *dst, socklen_t len)
+{
+ int ret;
+
+ pthread_cleanup_push(cleanup_file, (void *)(intptr_t)fd);
+ ret = connect(fd, dst, len);
+ pthread_cleanup_pop(ret == -1);
+ return ret;
+}
+
static int _xcb_open_tcp(char *host, char *protocol, const unsigned short port);
static int _xcb_open_unix(char *protocol, const char *file);
#ifdef DNETCONN
@@ -189,7 +199,6 @@ static int _xcb_open_decnet(const char *host, const char *protocol, const unsign
struct sockaddr_dn addr;
struct accessdata_dn accessdata;
struct nodeent *nodeaddr = getnodebyname(host);
- int cancel;
if(!nodeaddr)
return -1;
@@ -215,17 +224,17 @@ static int _xcb_open_decnet(const char *host, const char *protocol, const unsign
return -1;
setsockopt(fd, DNPROTO_NSP, SO_CONACCESS, &accessdata, sizeof(accessdata));
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel);
- if(connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
- close(fd);
- pthread_setcancelstate(cancel, NULL);
+ if(_xcb_connect_safe(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
return -1;
- }
- pthread_setcancelstate(cancel, NULL);
return fd;
}
#endif
+static void cleanup_addrinfo(void *data)
+{
+ freeaddrinfo(data);
+}
+
static int _xcb_open_tcp(char *host, char *protocol, const unsigned short port)
{
int fd = -1;
@@ -233,7 +242,6 @@ static int _xcb_open_tcp(char *host, char *protocol, const unsigned short port)
char service[6]; /* "65535" with the trailing '\0' */
struct addrinfo *results, *addr;
char *bracket;
- int cancel;
if (protocol && strcmp("tcp",protocol))
return -1;
@@ -261,15 +269,13 @@ static int _xcb_open_tcp(char *host, char *protocol, const unsigned short port)
snprintf(service, sizeof(service), "%hu", port);
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel);
if(getaddrinfo(host, service, &hints, &results))
{
- pthread_setcancelstate(cancel, NULL);
/* FIXME: use gai_strerror, and fill in error connection */
return -1;
}
- pthread_setcancelstate(cancel, NULL);
+ pthread_cleanup_push(cleanup_addrinfo, results);
for(addr = results; addr; addr = addr->ai_next)
{
fd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
@@ -278,25 +284,18 @@ static int _xcb_open_tcp(char *host, char *protocol, const unsigned short port)
setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on));
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel);
- if (connect(fd, addr->ai_addr, addr->ai_addrlen) >= 0)
- {
- pthread_setcancelstate(cancel, NULL);
+ if(_xcb_connect_safe(fd, addr->ai_addr, addr->ai_addrlen) >= 0)
break;
- }
- close(fd);
- pthread_setcancelstate(cancel, NULL);
fd = -1;
}
}
- freeaddrinfo(results);
+ pthread_cleanup_pop(1);
return fd;
}
static int _xcb_open_unix(char *protocol, const char *file)
{
int fd;
- int cancel;
struct sockaddr_un addr;
if (protocol && strcmp("unix",protocol))
@@ -310,13 +309,8 @@ static int _xcb_open_unix(char *protocol, const char *file)
fd = socket(AF_UNIX, SOCK_STREAM, 0);
if(fd == -1)
return -1;
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel);
- if(connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
- close(fd);
- pthread_setcancelstate(cancel, NULL);
+ if(_xcb_connect_safe(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
return -1;
- }
- pthread_setcancelstate(cancel, NULL);
return fd;
}
@@ -324,7 +318,6 @@ static int _xcb_open_unix(char *protocol, const char *file)
static int _xcb_open_abstract(char *protocol, const char *file, size_t filelen)
{
int fd;
- int cancel;
struct sockaddr_un addr = {0};
socklen_t namelen;
@@ -340,13 +333,8 @@ static int _xcb_open_abstract(char *protocol, const char *file, size_t filelen)
fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd == -1)
return -1;
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel);
- if (connect(fd, (struct sockaddr *) &addr, namelen) == -1) {
- close(fd);
- pthread_setcancelstate(cancel, NULL);
+ if (_xcb_connect_safe(fd, (struct sockaddr *) &addr, namelen) == -1)
return -1;
- }
- pthread_setcancelstate(cancel, NULL);
return fd;
}
#endif
--
1.6.6
More information about the Xcb
mailing list