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/usocket.c | |
| parent | 1ce47ebe3942a8b18b3b709f1ad915ac9ce82782 (diff) | |
| download | luasocket-a193c087a406f3f9b9d86f452a80b749f8d88301.tar.gz luasocket-a193c087a406f3f9b9d86f452a80b749f8d88301.tar.bz2 luasocket-a193c087a406f3f9b9d86f452a80b749f8d88301.zip | |
Fixing send/recv and optimizing.
Diffstat (limited to 'src/usocket.c')
| -rw-r--r-- | src/usocket.c | 45 |
1 files changed, 27 insertions, 18 deletions
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"; |
