diff options
| author | Diego Nehab <diego@tecgraf.puc-rio.br> | 2004-06-23 01:08:54 +0000 |
|---|---|---|
| committer | Diego Nehab <diego@tecgraf.puc-rio.br> | 2004-06-23 01:08:54 +0000 |
| commit | a193c087a406f3f9b9d86f452a80b749f8d88301 (patch) | |
| tree | 5576013d24b48d493dba776bc549e25daf1e0d81 /src | |
| parent | 1ce47ebe3942a8b18b3b709f1ad915ac9ce82782 (diff) | |
| download | luasocket-a193c087a406f3f9b9d86f452a80b749f8d88301.tar.gz luasocket-a193c087a406f3f9b9d86f452a80b749f8d88301.tar.bz2 luasocket-a193c087a406f3f9b9d86f452a80b749f8d88301.zip | |
Fixing send/recv and optimizing.
Diffstat (limited to 'src')
| -rw-r--r-- | src/socket.h | 2 | ||||
| -rw-r--r-- | src/usocket.c | 45 | ||||
| -rw-r--r-- | src/wsocket.c | 9 |
3 files changed, 35 insertions, 21 deletions
diff --git a/src/socket.h b/src/socket.h index 3dac875..5da1ccc 100644 --- a/src/socket.h +++ b/src/socket.h | |||
| @@ -60,6 +60,6 @@ const char *sock_listen(p_sock ps, int backlog); | |||
| 60 | const char *sock_accept(p_sock ps, p_sock pa, SA *addr, | 60 | const char *sock_accept(p_sock ps, p_sock pa, SA *addr, |
| 61 | socklen_t *addr_len, p_tm tm); | 61 | socklen_t *addr_len, p_tm tm); |
| 62 | 62 | ||
| 63 | const char *sock_hoststrerror(); | 63 | const char *sock_hoststrerror(void); |
| 64 | 64 | ||
| 65 | #endif /* SOCK_H */ | 65 | #endif /* SOCK_H */ |
diff --git a/src/usocket.c b/src/usocket.c index 617b1ea..cf0458d 100644 --- a/src/usocket.c +++ b/src/usocket.c | |||
| @@ -113,7 +113,7 @@ const char *sock_connect(p_sock ps, SA *addr, socklen_t addr_len, p_tm tm) | |||
| 113 | if (err > 0) { | 113 | if (err > 0) { |
| 114 | char dummy; | 114 | char dummy; |
| 115 | /* recv will set errno to the value a blocking connect would set */ | 115 | /* recv will set errno to the value a blocking connect would set */ |
| 116 | if (recv(sock, &dummy, 0, 0) < 0 && errno != EWOULDBLOCK) | 116 | if (recv(sock, &dummy, 0, 0) < 0 && errno != EAGAIN) |
| 117 | return sock_connectstrerror(errno); | 117 | return sock_connectstrerror(errno); |
| 118 | else | 118 | else |
| 119 | return NULL; | 119 | return NULL; |
| @@ -179,7 +179,7 @@ const char *sock_accept(p_sock ps, p_sock pa, SA *addr, | |||
| 179 | /* if result is valid, we are done */ | 179 | /* if result is valid, we are done */ |
| 180 | if (*pa != SOCK_INVALID) return NULL; | 180 | if (*pa != SOCK_INVALID) return NULL; |
| 181 | /* find out if we failed for a fatal reason */ | 181 | /* find out if we failed for a fatal reason */ |
| 182 | if (errno != EWOULDBLOCK && errno != ECONNABORTED) | 182 | if (errno != EAGAIN && errno != ECONNABORTED) |
| 183 | return sock_acceptstrerror(errno); | 183 | return sock_acceptstrerror(errno); |
| 184 | /* call select to avoid busy-wait. */ | 184 | /* call select to avoid busy-wait. */ |
| 185 | FD_ZERO(&fds); | 185 | FD_ZERO(&fds); |
| @@ -206,21 +206,23 @@ int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, | |||
| 206 | while (put < 0 && errno == EINTR); | 206 | while (put < 0 && errno == EINTR); |
| 207 | /* deal with failure */ | 207 | /* deal with failure */ |
| 208 | if (put <= 0) { | 208 | if (put <= 0) { |
| 209 | int ret; | ||
| 209 | fd_set fds; | 210 | fd_set fds; |
| 210 | /* in any case, nothing has been sent */ | 211 | /* in any case, nothing has been sent */ |
| 211 | *sent = 0; | 212 | *sent = 0; |
| 213 | /* only proceed to select if no error happened */ | ||
| 214 | if (errno != EAGAIN) return IO_ERROR; | ||
| 215 | /* optimize for the timeout = 0 case */ | ||
| 216 | if (timeout == 0) return IO_TIMEOUT; | ||
| 212 | /* here we know the connection has been closed */ | 217 | /* here we know the connection has been closed */ |
| 213 | if (errno == EPIPE) return IO_CLOSED; | 218 | if (errno == EPIPE) return IO_CLOSED; |
| 214 | /* run select to avoid busy wait */ | 219 | /* run select to avoid busy wait */ |
| 215 | FD_ZERO(&fds); | 220 | FD_ZERO(&fds); |
| 216 | FD_SET(sock, &fds); | 221 | FD_SET(sock, &fds); |
| 217 | if (sock_select(sock+1, NULL, &fds, NULL, timeout) <= 0) { | 222 | ret = sock_select(sock+1, NULL, &fds, NULL, timeout); |
| 218 | /* here the call was interrupted. calling again might work */ | 223 | if (ret == 0) return IO_TIMEOUT; |
| 219 | if (errno == EINTR) return IO_RETRY; | 224 | else if (ret > 0 || errno == EINTR) return IO_RETRY; |
| 220 | /* here there was no data before timeout */ | 225 | else return IO_ERROR; |
| 221 | else return IO_TIMEOUT; | ||
| 222 | /* here we didn't send anything, but now we can */ | ||
| 223 | } else return IO_RETRY; | ||
| 224 | /* here we successfully sent something */ | 226 | /* here we successfully sent something */ |
| 225 | } else { | 227 | } else { |
| 226 | *sent = put; | 228 | *sent = put; |
| @@ -240,15 +242,18 @@ int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent, | |||
| 240 | do put = sendto(sock, data, count, 0, addr, addr_len); | 242 | do put = sendto(sock, data, count, 0, addr, addr_len); |
| 241 | while (put < 0 && errno == EINTR); | 243 | while (put < 0 && errno == EINTR); |
| 242 | if (put <= 0) { | 244 | if (put <= 0) { |
| 245 | int ret; | ||
| 243 | fd_set fds; | 246 | fd_set fds; |
| 244 | *sent = 0; | 247 | *sent = 0; |
| 248 | if (errno != EAGAIN) return IO_ERROR; | ||
| 249 | if (timeout == 0) return IO_TIMEOUT; | ||
| 245 | if (errno == EPIPE) return IO_CLOSED; | 250 | if (errno == EPIPE) return IO_CLOSED; |
| 246 | FD_ZERO(&fds); | 251 | FD_ZERO(&fds); |
| 247 | FD_SET(sock, &fds); | 252 | FD_SET(sock, &fds); |
| 248 | if (sock_select(sock+1, NULL, &fds, NULL, timeout) <= 0) { | 253 | ret = sock_select(sock+1, NULL, &fds, NULL, timeout); |
| 249 | if (errno == EINTR) return IO_RETRY; | 254 | if (ret == 0) return IO_TIMEOUT; |
| 250 | else return IO_TIMEOUT; | 255 | else if (ret > 0 || errno == EINTR) return IO_RETRY; |
| 251 | } else return IO_RETRY; | 256 | else return IO_ERROR; |
| 252 | } else { | 257 | } else { |
| 253 | *sent = put; | 258 | *sent = put; |
| 254 | return IO_DONE; | 259 | return IO_DONE; |
| @@ -270,12 +275,14 @@ int sock_recv(p_sock ps, char *data, size_t count, size_t *got, int timeout) | |||
| 270 | int ret; | 275 | int ret; |
| 271 | *got = 0; | 276 | *got = 0; |
| 272 | if (taken == 0) return IO_CLOSED; | 277 | if (taken == 0) return IO_CLOSED; |
| 278 | if (errno != EAGAIN) return IO_ERROR; | ||
| 279 | if (timeout == 0) return IO_TIMEOUT; | ||
| 273 | FD_ZERO(&fds); | 280 | FD_ZERO(&fds); |
| 274 | FD_SET(sock, &fds); | 281 | FD_SET(sock, &fds); |
| 275 | ret = sock_select(sock+1, &fds, NULL, NULL, timeout); | 282 | ret = sock_select(sock+1, &fds, NULL, NULL, timeout); |
| 276 | if (ret < 0 && errno == EINTR) return IO_RETRY; | ||
| 277 | if (ret == 0) return IO_TIMEOUT; | 283 | if (ret == 0) return IO_TIMEOUT; |
| 278 | return IO_RETRY; | 284 | else if (ret > 0 || errno == EINTR) return IO_RETRY; |
| 285 | else return IO_ERROR; | ||
| 279 | } else { | 286 | } else { |
| 280 | *got = taken; | 287 | *got = taken; |
| 281 | return IO_DONE; | 288 | return IO_DONE; |
| @@ -298,12 +305,14 @@ int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got, | |||
| 298 | int ret; | 305 | int ret; |
| 299 | *got = 0; | 306 | *got = 0; |
| 300 | if (taken == 0) return IO_CLOSED; | 307 | if (taken == 0) return IO_CLOSED; |
| 308 | if (errno != EAGAIN) return IO_ERROR; | ||
| 309 | if (timeout == 0) return IO_TIMEOUT; | ||
| 301 | FD_ZERO(&fds); | 310 | FD_ZERO(&fds); |
| 302 | FD_SET(sock, &fds); | 311 | FD_SET(sock, &fds); |
| 303 | ret = sock_select(sock+1, &fds, NULL, NULL, timeout); | 312 | ret = sock_select(sock+1, &fds, NULL, NULL, timeout); |
| 304 | if (ret < 0 && errno == EINTR) return IO_RETRY; | ||
| 305 | if (ret == 0) return IO_TIMEOUT; | 313 | if (ret == 0) return IO_TIMEOUT; |
| 306 | return IO_RETRY; | 314 | else if (ret > 0 || errno == EINTR) return IO_RETRY; |
| 315 | else return IO_ERROR; | ||
| 307 | } else { | 316 | } else { |
| 308 | *got = taken; | 317 | *got = taken; |
| 309 | return IO_DONE; | 318 | return IO_DONE; |
| @@ -363,7 +372,7 @@ static const char *sock_createstrerror(int err) | |||
| 363 | static const char *sock_acceptstrerror(int err) | 372 | static const char *sock_acceptstrerror(int err) |
| 364 | { | 373 | { |
| 365 | switch (err) { | 374 | switch (err) { |
| 366 | case EWOULDBLOCK: return io_strerror(IO_RETRY); | 375 | case EAGAIN: return io_strerror(IO_RETRY); |
| 367 | case EBADF: return "invalid descriptor"; | 376 | case EBADF: return "invalid descriptor"; |
| 368 | case ENOBUFS: case ENOMEM: return "insuffucient buffer space"; | 377 | case ENOBUFS: case ENOMEM: return "insuffucient buffer space"; |
| 369 | case ENOTSOCK: return "descriptor not a socket"; | 378 | case ENOTSOCK: return "descriptor not a socket"; |
diff --git a/src/wsocket.c b/src/wsocket.c index e276fe0..7f3e066 100644 --- a/src/wsocket.c +++ b/src/wsocket.c | |||
| @@ -200,7 +200,6 @@ int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, | |||
| 200 | { | 200 | { |
| 201 | t_sock sock = *ps; | 201 | t_sock sock = *ps; |
| 202 | int put; | 202 | int put; |
| 203 | int ret; | ||
| 204 | /* avoid making system calls on closed sockets */ | 203 | /* avoid making system calls on closed sockets */ |
| 205 | if (sock == SOCK_INVALID) return IO_CLOSED; | 204 | if (sock == SOCK_INVALID) return IO_CLOSED; |
| 206 | /* try to send something */ | 205 | /* try to send something */ |
| @@ -212,6 +211,9 @@ int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, | |||
| 212 | /* run select to avoid busy wait */ | 211 | /* run select to avoid busy wait */ |
| 213 | if (WSAGetLastError() == WSAEWOULDBLOCK) { | 212 | if (WSAGetLastError() == WSAEWOULDBLOCK) { |
| 214 | fd_set fds; | 213 | fd_set fds; |
| 214 | int ret; | ||
| 215 | /* optimize for the timeout = 0 case */ | ||
| 216 | if (timeout == 0) return IO_TIMEOUT; | ||
| 215 | FD_ZERO(&fds); | 217 | FD_ZERO(&fds); |
| 216 | FD_SET(sock, &fds); | 218 | FD_SET(sock, &fds); |
| 217 | ret = sock_select(0, NULL, &fds, NULL, timeout); | 219 | ret = sock_select(0, NULL, &fds, NULL, timeout); |
| @@ -236,13 +238,14 @@ int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent, | |||
| 236 | { | 238 | { |
| 237 | t_sock sock = *ps; | 239 | t_sock sock = *ps; |
| 238 | int put; | 240 | int put; |
| 239 | int ret; | ||
| 240 | if (sock == SOCK_INVALID) return IO_CLOSED; | 241 | if (sock == SOCK_INVALID) return IO_CLOSED; |
| 241 | put = sendto(sock, data, (int) count, 0, addr, addr_len); | 242 | put = sendto(sock, data, (int) count, 0, addr, addr_len); |
| 242 | if (put <= 0) { | 243 | if (put <= 0) { |
| 243 | *sent = 0; | 244 | *sent = 0; |
| 244 | if (WSAGetLastError() == WSAEWOULDBLOCK) { | 245 | if (WSAGetLastError() == WSAEWOULDBLOCK) { |
| 245 | fd_set fds; | 246 | fd_set fds; |
| 247 | int ret; | ||
| 248 | if (timeout == 0) return IO_TIMEOUT; | ||
| 246 | FD_ZERO(&fds); | 249 | FD_ZERO(&fds); |
| 247 | FD_SET(sock, &fds); | 250 | FD_SET(sock, &fds); |
| 248 | ret = sock_select(0, NULL, &fds, NULL, timeout); | 251 | ret = sock_select(0, NULL, &fds, NULL, timeout); |
| @@ -269,6 +272,7 @@ int sock_recv(p_sock ps, char *data, size_t count, size_t *got, int timeout) | |||
| 269 | int ret; | 272 | int ret; |
| 270 | *got = 0; | 273 | *got = 0; |
| 271 | if (taken == 0 || WSAGetLastError() != WSAEWOULDBLOCK) return IO_CLOSED; | 274 | if (taken == 0 || WSAGetLastError() != WSAEWOULDBLOCK) return IO_CLOSED; |
| 275 | if (timeout == 0) return IO_TIMEOUT; | ||
| 272 | FD_ZERO(&fds); | 276 | FD_ZERO(&fds); |
| 273 | FD_SET(sock, &fds); | 277 | FD_SET(sock, &fds); |
| 274 | ret = sock_select(0, &fds, NULL, NULL, timeout); | 278 | ret = sock_select(0, &fds, NULL, NULL, timeout); |
| @@ -295,6 +299,7 @@ int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got, | |||
| 295 | int ret; | 299 | int ret; |
| 296 | *got = 0; | 300 | *got = 0; |
| 297 | if (taken == 0 || WSAGetLastError() != WSAEWOULDBLOCK) return IO_CLOSED; | 301 | if (taken == 0 || WSAGetLastError() != WSAEWOULDBLOCK) return IO_CLOSED; |
| 302 | if (timeout == 0) return IO_TIMEOUT; | ||
| 298 | FD_ZERO(&fds); | 303 | FD_ZERO(&fds); |
| 299 | FD_SET(sock, &fds); | 304 | FD_SET(sock, &fds); |
| 300 | ret = sock_select(0, &fds, NULL, NULL, timeout); | 305 | ret = sock_select(0, &fds, NULL, NULL, timeout); |
