diff options
| author | Michael Adam <obnox@samba.org> | 2016-09-14 13:24:47 +0200 |
|---|---|---|
| committer | Andreas Schneider <asn@samba.org> | 2016-10-20 10:51:59 +0200 |
| commit | f9fbda9ef0f7b279e8e618a3888ab2e50884da1b (patch) | |
| tree | 7a4e9501b0cc0203e6fc2087cdffc65e484307a8 /src | |
| parent | 69aee42f1d4a0e563b9e85e899dc8b4f18303af0 (diff) | |
| download | socket_wrapper-f9fbda9ef0f7b279e8e618a3888ab2e50884da1b.tar.gz socket_wrapper-f9fbda9ef0f7b279e8e618a3888ab2e50884da1b.tar.xz socket_wrapper-f9fbda9ef0f7b279e8e618a3888ab2e50884da1b.zip | |
swrap: Introduce a freelist in the socket_info array
Signed-off-by: Michael Adam <obnox@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
Diffstat (limited to 'src')
| -rw-r--r-- | src/socket_wrapper.c | 44 |
1 files changed, 37 insertions, 7 deletions
diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c index ad7f682..84dfc07 100644 --- a/src/socket_wrapper.c +++ b/src/socket_wrapper.c @@ -263,10 +263,14 @@ struct socket_info_fd { int si_index; }; +int first_free; + struct socket_info { unsigned int refcount; + int next_free; + int family; int type; int protocol; @@ -1030,6 +1034,7 @@ done: static void socket_wrapper_init_sockets(void) { + size_t i; if (sockets != NULL) { return; @@ -1045,6 +1050,14 @@ static void socket_wrapper_init_sockets(void) "Failed to allocate sockets array.\n"); exit(-1); } + + first_free = 0; + + for (i = 0; i < max_sockets; i++) { + sockets[i].next_free = i+1; + } + + sockets[max_sockets-1].next_free = -1; } bool socket_wrapper_enabled(void) @@ -1075,18 +1088,23 @@ static unsigned int socket_wrapper_default_iface(void) return 1;/* 127.0.0.1 */ } +/* + * Return the first free entry (if any) and make + * it re-usable again (by nulling it out) + */ static int socket_wrapper_first_free_index(void) { - unsigned int i; + int next_free; - for (i = 0; i < max_sockets; ++i) { - if (sockets[i].refcount == 0) { - ZERO_STRUCT(sockets[i]); - return i; - } + if (first_free == -1) { + return -1; } - return -1; + next_free = sockets[first_free].next_free; + ZERO_STRUCT(sockets[first_free]); + sockets[first_free].next_free = next_free; + + return first_free; } static int convert_un_in(const struct sockaddr_un *un, struct sockaddr *in, socklen_t *len) @@ -1607,6 +1625,9 @@ static void swrap_remove_stale(int fd) if (si->un_addr.sun_path[0] != '\0') { unlink(si->un_addr.sun_path); } + + si->next_free = first_free; + first_free = fi->si_index; } static int sockaddr_convert_to_un(struct socket_info *si, @@ -2629,6 +2650,9 @@ static int swrap_socket(int family, int type, int protocol) } si->refcount = 1; + first_free = si->next_free; + si->next_free = 0; + fi->fd = fd; fi->si_index = idx; @@ -2854,6 +2878,9 @@ static int swrap_accept(int s, memcpy(&child_si->myname.sa.ss, &in_my_addr.sa.ss, in_my_addr.sa_socklen); child_si->refcount = 1; + first_free = child_si->next_free; + child_si->next_free = 0; + child_fi->si_index = idx; SWRAP_DLIST_ADD(socket_fds, child_fi); @@ -5239,6 +5266,9 @@ static int swrap_close(int fd) unlink(si->un_addr.sun_path); } + si->next_free = first_free; + first_free = fi->si_index; + return ret; } |
