diff options
| -rw-r--r-- | ot_event.c | 14 | ||||
| -rw-r--r-- | ot_event.h | 5 | ||||
| -rw-r--r-- | ot_http.c | 3 | ||||
| -rw-r--r-- | ot_socket.c | 13 |
4 files changed, 30 insertions, 5 deletions
| @@ -71,6 +71,10 @@ int event_add(int fd, int what, uint32_t generation) { return event_ctl(EPOLL_CT | |||
| 71 | int event_modify(int fd, int what, uint32_t generation) { return event_ctl(EPOLL_CTL_MOD, fd, what, generation); } | 71 | int event_modify(int fd, int what, uint32_t generation) { return event_ctl(EPOLL_CTL_MOD, fd, what, generation); } |
| 72 | int event_del(int fd) { return epoll_ctl(g_epoll, EPOLL_CTL_DEL, fd, NULL); } | 72 | int event_del(int fd) { return epoll_ctl(g_epoll, EPOLL_CTL_DEL, fd, NULL); } |
| 73 | 73 | ||
| 74 | /* A descriptor leaves the interest list when the last reference to its open | ||
| 75 | file description is closed, and the tracker never duplicates one */ | ||
| 76 | int event_close(int fd) { return close(fd); } | ||
| 77 | |||
| 74 | int event_wait(ot_event *out, int max, int timeout_ms) { | 78 | int event_wait(ot_event *out, int max, int timeout_ms) { |
| 75 | int count, i; | 79 | int count, i; |
| 76 | 80 | ||
| @@ -171,6 +175,9 @@ int event_add(int fd, int what, uint32_t generation) { return event_change(fd, w | |||
| 171 | int event_modify(int fd, int what, uint32_t generation) { return event_change(fd, what, generation, 0); } | 175 | int event_modify(int fd, int what, uint32_t generation) { return event_change(fd, what, generation, 0); } |
| 172 | int event_del(int fd) { return event_change(fd, 0, 0, 1); } | 176 | int event_del(int fd) { return event_change(fd, 0, 0, 1); } |
| 173 | 177 | ||
| 178 | /* Closing a descriptor removes every kevent that references it */ | ||
| 179 | int event_close(int fd) { return close(fd); } | ||
| 180 | |||
| 174 | int event_wait(ot_event *out, int max, int timeout_ms) { | 181 | int event_wait(ot_event *out, int max, int timeout_ms) { |
| 175 | struct timespec timeout; | 182 | struct timespec timeout; |
| 176 | struct timespec *deadline = NULL; | 183 | struct timespec *deadline = NULL; |
| @@ -311,6 +318,13 @@ int event_del(int fd) { | |||
| 311 | return 0; | 318 | return 0; |
| 312 | } | 319 | } |
| 313 | 320 | ||
| 321 | /* Nothing here lives in the kernel, so the entry has to come out by hand | ||
| 322 | before the descriptor goes, or poll reports POLLNVAL for it forever */ | ||
| 323 | int event_close(int fd) { | ||
| 324 | event_del(fd); | ||
| 325 | return close(fd); | ||
| 326 | } | ||
| 327 | |||
| 314 | int event_wait(ot_event *out, int max, int timeout_ms) { | 328 | int event_wait(ot_event *out, int max, int timeout_ms) { |
| 315 | int ready, found = 0, i; | 329 | int ready, found = 0, i; |
| 316 | 330 | ||
| @@ -29,6 +29,11 @@ int event_add(int fd, int what, uint32_t generation); | |||
| 29 | int event_modify(int fd, int what, uint32_t generation); | 29 | int event_modify(int fd, int what, uint32_t generation); |
| 30 | int event_del(int fd); | 30 | int event_del(int fd); |
| 31 | 31 | ||
| 32 | /* Stop watching a descriptor and close it. Where the kernel drops a closed | ||
| 33 | descriptor from its set by itself, this is one system call where doing the | ||
| 34 | two separately would be two. */ | ||
| 35 | int event_close(int fd); | ||
| 36 | |||
| 32 | /* Waits at most timeout_ms, or indefinitely when that is negative, and fills | 37 | /* Waits at most timeout_ms, or indefinitely when that is negative, and fills |
| 33 | out with up to max ready descriptors. Returns how many, or -1. */ | 38 | out with up to max ready descriptors. Returns how many, or -1. */ |
| 34 | int event_wait(ot_event *out, int max, int timeout_ms); | 39 | int event_wait(ot_event *out, int max, int timeout_ms); |
| @@ -56,8 +56,7 @@ void http_close(const int64_t sock) { | |||
| 56 | free(cookie); | 56 | free(cookie); |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | event_del((int)sock); | 59 | event_close((int)sock); |
| 60 | close((int)sock); | ||
| 61 | } | 60 | } |
| 62 | 61 | ||
| 63 | static void http_senddata(const int64_t sock, struct ot_workstruct *ws) { | 62 | static void http_senddata(const int64_t sock, struct ot_workstruct *ws) { |
diff --git a/ot_socket.c b/ot_socket.c index 158459f..47ed26d 100644 --- a/ot_socket.c +++ b/ot_socket.c | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | $id$ */ | 4 | $id$ */ |
| 5 | 5 | ||
| 6 | /* System */ | 6 | /* System */ |
| 7 | #define _GNU_SOURCE /* accept4 on glibc */ | ||
| 7 | #include <errno.h> | 8 | #include <errno.h> |
| 8 | #include <fcntl.h> | 9 | #include <fcntl.h> |
| 9 | #include <netinet/in.h> | 10 | #include <netinet/in.h> |
| @@ -170,19 +171,25 @@ int socket_is_connected(int s) { | |||
| 170 | return 1; | 171 | return 1; |
| 171 | } | 172 | } |
| 172 | 173 | ||
| 174 | /* Linux hands over a blocking socket whatever the listening socket was, the | ||
| 175 | BSDs and macOS inherit the listener's flags, so the accepted socket has to | ||
| 176 | be told either way. accept4 carries the flag itself, which saves the two | ||
| 177 | fcntl calls it otherwise takes. Darwin has neither accept4 nor the flag. */ | ||
| 173 | int socket_accept(int s, ot_ip6 ip, uint16_t *port) { | 178 | int socket_accept(int s, ot_ip6 ip, uint16_t *port) { |
| 174 | struct sockaddr_storage ss; | 179 | struct sockaddr_storage ss; |
| 175 | socklen_t len = sizeof(ss); | 180 | socklen_t len = sizeof(ss); |
| 176 | int fd; | 181 | int fd; |
| 177 | 182 | ||
| 178 | memset(&ss, 0, sizeof(ss)); | 183 | memset(&ss, 0, sizeof(ss)); |
| 184 | #ifdef SOCK_NONBLOCK | ||
| 185 | if ((fd = accept4(s, (struct sockaddr *)&ss, &len, SOCK_NONBLOCK)) == -1) | ||
| 186 | return -1; | ||
| 187 | #else | ||
| 179 | if ((fd = accept(s, (struct sockaddr *)&ss, &len)) == -1) | 188 | if ((fd = accept(s, (struct sockaddr *)&ss, &len)) == -1) |
| 180 | return -1; | 189 | return -1; |
| 181 | |||
| 182 | /* Linux hands over a blocking socket whatever the listening socket was, the | ||
| 183 | BSDs and macOS inherit the listener's flags, so say which one we want. */ | ||
| 184 | if (set_nonblocking(fd) == -1) | 190 | if (set_nonblocking(fd) == -1) |
| 185 | return close_and_fail(fd); | 191 | return close_and_fail(fd); |
| 192 | #endif | ||
| 186 | 193 | ||
| 187 | ip_from_sockaddr(ip, port, &ss); | 194 | ip_from_sockaddr(ip, port, &ss); |
| 188 | return fd; | 195 | return fd; |
