From e57f9e9964ac16b1fd09028ea533457f3029d296 Mon Sep 17 00:00:00 2001 From: Diego Nehab Date: Fri, 11 Mar 2005 00:20:21 +0000 Subject: [PATCH] Apparently, non-blocking connect doesn't work on windows if you use 0 timeout in the select call... --- luasocket.vcproj | 4 +- mime.vcproj | 4 +- samples/forward.lua | 138 +++++++++++++++++++++++--------------------- src/socket.h | 2 +- src/tcp.c | 6 +- src/usocket.c | 26 ++++----- src/wsocket.c | 26 ++++----- 7 files changed, 106 insertions(+), 100 deletions(-) diff --git a/luasocket.vcproj b/luasocket.vcproj index 14cbebf..71486d6 100644 --- a/luasocket.vcproj +++ b/luasocket.vcproj @@ -33,7 +33,7 @@ TIMEOUT then - -- only create table if someone is doomed + -- only create table if at least one is doomed deathrow = deathrow or {} deathrow[who] = true end diff --git a/src/socket.h b/src/socket.h index 639229d..4443bcc 100644 --- a/src/socket.h +++ b/src/socket.h @@ -49,7 +49,7 @@ int sock_recvfrom(p_sock ps, char *data, size_t count, void sock_setnonblocking(p_sock ps); void sock_setblocking(p_sock ps); -int sock_waitfd(int fd, int sw, p_tm tm); +int sock_waitfd(p_sock ps, int sw, p_tm tm); int sock_select(int n, fd_set *rfds, fd_set *wfds, fd_set *efds, p_tm tm); int sock_connect(p_sock ps, SA *addr, socklen_t addr_len, p_tm tm); diff --git a/src/tcp.c b/src/tcp.c index 162d5af..7ff3054 100644 --- a/src/tcp.c +++ b/src/tcp.c @@ -228,8 +228,10 @@ static int meth_connect(lua_State *L) static int meth_connected(lua_State *L) { - p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{master}", 1); - int err = sock_connected(&tcp->sock, &tcp->tm); + p_tcp tcp; + int err; + tcp = (p_tcp) aux_checkclass(L, "tcp{master}", 1); + err = sock_connected(&tcp->sock, &tcp->tm); if (err != IO_DONE) { lua_pushnil(L); lua_pushstring(L, sock_strerror(err)); diff --git a/src/usocket.c b/src/usocket.c index 3428a0c..3e151bf 100644 --- a/src/usocket.c +++ b/src/usocket.c @@ -22,10 +22,10 @@ #define WAITFD_R POLLIN #define WAITFD_W POLLOUT #define WAITFD_C (POLLIN|POLLOUT) -int sock_waitfd(int fd, int sw, p_tm tm) { +int sock_waitfd(p_sock ps, int sw, p_tm tm) { int ret; struct pollfd pfd; - pfd.fd = fd; + pfd.fd = *ps; pfd.events = sw; pfd.revents = 0; if (tm_iszero(tm)) return IO_TIMEOUT; /* optimize timeout == 0 case */ @@ -44,7 +44,7 @@ int sock_waitfd(int fd, int sw, p_tm tm) { #define WAITFD_W 2 #define WAITFD_C (WAITFD_R|WAITFD_W) -int sock_waitfd(int fd, int sw, p_tm tm) { +int sock_waitfd(p_sock ps, int sw, p_tm tm) { int ret; fd_set rfds, wfds, *rp, *wp; struct timeval tv, *tp; @@ -53,8 +53,8 @@ int sock_waitfd(int fd, int sw, p_tm tm) { do { /* must set bits within loop, because select may have modifed them */ rp = wp = NULL; - if (sw & WAITFD_R) { FD_ZERO(&rfds); FD_SET(fd, &rfds); rp = &rfds; } - if (sw & WAITFD_W) { FD_ZERO(&wfds); FD_SET(fd, &wfds); wp = &wfds; } + if (sw & WAITFD_R) { FD_ZERO(&rfds); FD_SET(*ps, &rfds); rp = &rfds; } + if (sw & WAITFD_W) { FD_ZERO(&wfds); FD_SET(*ps, &wfds); wp = &wfds; } t = tm_getretry(tm); tp = NULL; if (t >= 0.0) { @@ -62,11 +62,11 @@ int sock_waitfd(int fd, int sw, p_tm tm) { tv.tv_usec = (int)((t-tv.tv_sec)*1.0e6); tp = &tv; } - ret = select(fd+1, rp, wp, NULL, tp); + ret = select(*ps+1, rp, wp, NULL, tp); } while (ret == -1 && errno == EINTR); if (ret == -1) return errno; if (ret == 0) return IO_TIMEOUT; - if (sw == WAITFD_C && FD_ISSET(fd, &rfds)) return IO_CLOSED; + if (sw == WAITFD_C && FD_ISSET(*ps, &rfds)) return IO_CLOSED; return IO_DONE; } #endif @@ -177,7 +177,7 @@ int sock_connect(p_sock ps, SA *addr, socklen_t len, p_tm tm) { \*-------------------------------------------------------------------------*/ int sock_connected(p_sock ps, p_tm tm) { int err; - if ((err = sock_waitfd(*ps, WAITFD_C, tm) == IO_CLOSED)) { + if ((err = sock_waitfd(ps, WAITFD_C, tm) == IO_CLOSED)) { if (recv(*ps, (char *) &err, 0, 0) == 0) return IO_DONE; else return errno; } else return err; @@ -198,7 +198,7 @@ int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *len, p_tm tm) { err = errno; if (err == EINTR) continue; if (err != EAGAIN && err != ECONNABORTED) return err; - if ((err = sock_waitfd(*ps, WAITFD_R, tm)) != IO_DONE) return err; + if ((err = sock_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; } /* can't reach here */ return IO_UNKNOWN; @@ -230,7 +230,7 @@ int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, p_tm tm) /* if failed fatal reason, report error */ if (err != EAGAIN) return err; /* wait until we can send something or we timeout */ - if ((err = sock_waitfd(*ps, WAITFD_W, tm)) != IO_DONE) return err; + if ((err = sock_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err; } /* can't reach here */ return IO_UNKNOWN; @@ -255,7 +255,7 @@ int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent, if (put == 0 || err == EPIPE) return IO_CLOSED; if (err == EINTR) continue; if (err != EAGAIN) return err; - if ((err = sock_waitfd(*ps, WAITFD_W, tm)) != IO_DONE) return err; + if ((err = sock_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err; } return IO_UNKNOWN; } @@ -277,7 +277,7 @@ int sock_recv(p_sock ps, char *data, size_t count, size_t *got, p_tm tm) { if (taken == 0) return IO_CLOSED; if (err == EINTR) continue; if (err != EAGAIN) return err; - if ((err = sock_waitfd(*ps, WAITFD_R, tm)) != IO_DONE) return err; + if ((err = sock_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; } return IO_UNKNOWN; } @@ -300,7 +300,7 @@ int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got, if (taken == 0) return IO_CLOSED; if (err == EINTR) continue; if (err != EAGAIN) return err; - if ((err = sock_waitfd(*ps, WAITFD_R, tm)) != IO_DONE) return err; + if ((err = sock_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; } return IO_UNKNOWN; } diff --git a/src/wsocket.c b/src/wsocket.c index c0686cd..8b00fa5 100644 --- a/src/wsocket.c +++ b/src/wsocket.c @@ -45,15 +45,15 @@ int sock_close(void) { #define WAITFD_E 4 #define WAITFD_C (WAITFD_E|WAITFD_W) -int sock_waitfd(t_sock fd, int sw, p_tm tm) { +int sock_waitfd(p_sock ps, int sw, p_tm tm) { int ret; fd_set rfds, wfds, efds, *rp = NULL, *wp = NULL, *ep = NULL; struct timeval tv, *tp = NULL; double t; if (tm_iszero(tm)) return IO_TIMEOUT; /* optimize timeout == 0 case */ - if (sw & WAITFD_R) { FD_ZERO(&rfds); FD_SET(fd, &rfds); rp = &rfds; } - if (sw & WAITFD_W) { FD_ZERO(&wfds); FD_SET(fd, &wfds); wp = &wfds; } - if (sw & WAITFD_C) { FD_ZERO(&efds); FD_SET(fd, &efds); ep = &efds; } + if (sw & WAITFD_R) { FD_ZERO(&rfds); FD_SET(*ps, &rfds); rp = &rfds; } + if (sw & WAITFD_W) { FD_ZERO(&wfds); FD_SET(*ps, &wfds); wp = &wfds; } + if (sw & WAITFD_C) { FD_ZERO(&efds); FD_SET(*ps, &efds); ep = &efds; } if ((t = tm_get(tm)) >= 0.0) { tv.tv_sec = (int) t; tv.tv_usec = (int) ((t-tv.tv_sec)*1.0e6); @@ -62,7 +62,7 @@ int sock_waitfd(t_sock fd, int sw, p_tm tm) { ret = select(0, rp, wp, ep, tp); if (ret == -1) return WSAGetLastError(); if (ret == 0) return IO_TIMEOUT; - if (sw == WAITFD_C && FD_ISSET(fd, &efds)) return IO_CLOSED; + if (sw == WAITFD_C && FD_ISSET(*ps, &efds)) return IO_CLOSED; return IO_DONE; } @@ -127,15 +127,15 @@ int sock_connect(p_sock ps, SA *addr, socklen_t len, p_tm tm) { /*-------------------------------------------------------------------------*\ * Check if socket is connected \*-------------------------------------------------------------------------*/ -int sock_connected(p_sock ps) { +int sock_connected(p_sock ps, p_tm tm) { int err; - if ((err = sock_waitfd(*ps, WAITFD_C, tm)) == IO_CLOSED) { + if ((err = sock_waitfd(ps, WAITFD_C, tm)) == IO_CLOSED) { int len = sizeof(err); /* give windows time to set the error (yes, disgusting) */ Sleep(0); /* find out why we failed */ getsockopt(*ps, SOL_SOCKET, SO_ERROR, (char *)&err, &len); - /* we KNOW there was an error. if why is 0, we will return + /* we KNOW there was an error. if 'why' is 0, we will return * "unknown error", but it's not really our fault */ return err > 0? err: IO_UNKNOWN; } else return err; @@ -181,7 +181,7 @@ int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *len, p_tm tm) { /* if we failed because there was no connectoin, keep trying */ if (err != WSAEWOULDBLOCK && err != WSAECONNABORTED) return err; /* call select to avoid busy wait */ - if ((err = sock_waitfd(*ps, WAITFD_R, tm)) != IO_DONE) return err; + if ((err = sock_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; } /* can't reach here */ return IO_UNKNOWN; @@ -213,7 +213,7 @@ int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, p_tm tm) /* we can only proceed if there was no serious error */ if (err != WSAEWOULDBLOCK) return err; /* avoid busy wait */ - if ((err = sock_waitfd(*ps, WAITFD_W, tm)) != IO_DONE) return err; + if ((err = sock_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err; } /* can't reach here */ return IO_UNKNOWN; @@ -236,7 +236,7 @@ int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent, } err = WSAGetLastError(); if (err != WSAEWOULDBLOCK) return err; - if ((err = sock_waitfd(*ps, WAITFD_W, tm)) != IO_DONE) return err; + if ((err = sock_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err; } return IO_UNKNOWN; } @@ -257,7 +257,7 @@ int sock_recv(p_sock ps, char *data, size_t count, size_t *got, p_tm tm) { if (taken == 0) return IO_CLOSED; err = WSAGetLastError(); if (err != WSAEWOULDBLOCK) return err; - if ((err = sock_waitfd(*ps, WAITFD_R, tm)) != IO_DONE) return err; + if ((err = sock_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; } return IO_UNKNOWN; } @@ -279,7 +279,7 @@ int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got, if (taken == 0) return IO_CLOSED; err = WSAGetLastError(); if (err != WSAEWOULDBLOCK) return err; - if ((err = sock_waitfd(*ps, WAITFD_R, tm)) != IO_DONE) return err; + if ((err = sock_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; } return IO_UNKNOWN; }