diff options
Diffstat (limited to 'libxcb/src/xcb_conn.c')
-rw-r--r-- | libxcb/src/xcb_conn.c | 48 |
1 files changed, 38 insertions, 10 deletions
diff --git a/libxcb/src/xcb_conn.c b/libxcb/src/xcb_conn.c index 7979491d3..45ada1fb7 100644 --- a/libxcb/src/xcb_conn.c +++ b/libxcb/src/xcb_conn.c @@ -52,6 +52,12 @@ #include <netinet/in.h> #endif /* _WIN32 */ +#include <X11/Xtrans/Xtrans.h> + +#ifdef _MSC_VER +#define _close(fd) closesocket(fd) +#endif + /* SHUT_RDWR is fairly recent and is not available on all platforms */ #if !defined(SHUT_RDWR) #define SHUT_RDWR 2 @@ -74,7 +80,7 @@ static int set_fd_flags(const int fd) #ifdef _WIN32 u_long iMode = 1; /* non-zero puts it in non-blocking mode, 0 in blocking mode */ - int ret = 0; + int ret; ret = ioctlsocket(fd, FIONBIO, &iMode); if(ret != 0) @@ -114,7 +120,7 @@ static int write_setup(xcb_connection_t *c, xcb_auth_info_t *auth_info) out.authorization_protocol_name_len = 0; out.authorization_protocol_data_len = 0; parts[count].iov_len = sizeof(xcb_setup_request_t); - parts[count++].iov_base = &out; + parts[count++].iov_base = (caddr_t) &out; parts[count].iov_len = XCB_PAD(sizeof(xcb_setup_request_t)); parts[count++].iov_base = (char *) pad; @@ -182,33 +188,48 @@ static int read_setup(xcb_connection_t *c) static int write_vec(xcb_connection_t *c, struct iovec **vector, int *count) { int n; - assert(!c->out.queue_len); #ifdef _WIN32 int i = 0; - int ret = 0,err = 0; + int cnt=*count; struct iovec *vec; n = 0; + assert(!c->out.queue_len); /* Could use the WSASend win32 function for scatter/gather i/o but setting up the WSABUF struct from an iovec would require more work and I'm not sure of the benefit....works for now */ vec = *vector; - while(i < *count) + while(i < cnt) { - ret = send(c->fd,vec->iov_base,vec->iov_len,0); + char *p= vec->iov_base; + size_t l= vec->iov_len; + while (l > 0) + { + int ret = send(c->fd, p, l, 0); if(ret == SOCKET_ERROR) { - err = WSAGetLastError(); + int err = WSAGetLastError(); if(err == WSAEWOULDBLOCK) { - return 1; + if (n) + { + /* already return the data */ + i=cnt; + break; + } + else + return 1; } } + p += ret; + l -= ret; n += ret; - *vec++; - i++; + } + vec++; + i++; } #else + assert(!c->out.queue_len); n = writev(c->fd, *vector, *count); if(n < 0 && errno == EAGAIN) return 1; @@ -416,6 +437,13 @@ int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vec } #else ret = select(c->fd + 1, &rfds, &wfds, 0, 0); + if (ret==SOCKET_ERROR) + { + ret=-1; + errno = WSAGetLastError(); + if (errno == WSAEINTR) + errno=EINTR; + } #endif } while (ret == -1 && errno == EINTR); if(ret < 0) |