summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Adam <obnox@samba.org>2016-09-14 13:24:47 +0200
committerAndreas Schneider <asn@samba.org>2016-10-20 10:51:59 +0200
commitf9fbda9ef0f7b279e8e618a3888ab2e50884da1b (patch)
tree7a4e9501b0cc0203e6fc2087cdffc65e484307a8
parent69aee42f1d4a0e563b9e85e899dc8b4f18303af0 (diff)
downloadsocket_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>
-rw-r--r--src/socket_wrapper.c44
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;
}