diff options
author | Gleb Smirnoff <glebius@FreeBSD.org> | 2025-01-20 21:15:39 +0000 |
---|---|---|
committer | Gleb Smirnoff <glebius@FreeBSD.org> | 2025-01-20 21:15:39 +0000 |
commit | ddc7fd6641c38a00d8d299d69ba57f0657f5eaac (patch) | |
tree | 864efe5c83bd4c59a9b4d31115a20a0261d8bf6b | |
parent | dae4eb623e862789533dca8b644ea531502a088f (diff) |
netlink: provide snl_clone() to create a secondary snl state
The function will clone an existing snl_state(). The clone points at the
same socket, but has a separate allocator. Closing a clone frees the
memory, but doesn't close the socket. Such clones are handy in a
multithreaded process that has a single socket with multiple writers and a
serialized reader. It can be easily extended to support multiple readers,
too, but now there is no use.
Reviewed by: melifaro
Differential Revision: https://reviews.freebsd.org/D48568
-rw-r--r-- | sys/netlink/netlink_snl.h | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/sys/netlink/netlink_snl.h b/sys/netlink/netlink_snl.h index 44967b6f444a..faaeebe52eac 100644 --- a/sys/netlink/netlink_snl.h +++ b/sys/netlink/netlink_snl.h @@ -240,14 +240,13 @@ snl_clear_lb(struct snl_state *ss) static void snl_free(struct snl_state *ss) { - if (ss->init_done) { + if (ss->init_done) close(ss->fd); - if (ss->buf != NULL) - free(ss->buf); - if (ss->lb != NULL) { - snl_clear_lb(ss); - lb_free(ss->lb); - } + if (ss->buf != NULL) + free(ss->buf); + if (ss->lb != NULL) { + snl_clear_lb(ss); + lb_free(ss->lb); } } @@ -291,6 +290,16 @@ snl_init(struct snl_state *ss, int netlink_family) } static inline bool +snl_clone(struct snl_state *ss, const struct snl_state *orig) +{ + *ss = (struct snl_state){ + .fd = orig->fd, + .init_done = false, + }; + return ((ss->lb = lb_init(SCRATCH_BUFFER_SIZE)) != NULL); +} + +static inline bool snl_send(struct snl_state *ss, void *data, int sz) { return (send(ss->fd, data, sz, 0) == sz); |