Add a socket destructor callback. This allows kernel providers to set

callbacks to perform additional cleanup actions at the time a socket is
closed.

Michio Honda presented a use for this at BSDCan 2018.
(See https://www.bsdcan.org/2018/schedule/events/965.en.html .)

Submitted by:	Michio Honda <micchie at sfc.wide.ad.jp> (previous version)
Reviewed by:	lstewart (previous version)
Differential Revision:	https://reviews.freebsd.org/D15706
This commit is contained in:
jtl 2018-06-08 19:35:24 +00:00
parent 02bd135356
commit 7cf8a13d28
3 changed files with 29 additions and 1 deletions

View File

@ -26,7 +26,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd May 26, 2014
.Dd June 8, 2018
.Dt SOCKET 9
.Os
.Sh NAME
@ -54,6 +54,11 @@
.Fc
.Ft int
.Fn sodisconnect "struct socket *so"
.Ft void
.Fo sodtor_set
.Fa "struct socket *so"
.Fa "void (*func)(struct socket *)"
.Fc
.Ft struct sockaddr *
.Fn sodupsockaddr "const struct sockaddr *sa" "int mflags"
.Ft void
@ -369,6 +374,13 @@ be cleared, with
.Dv SO_RCV
or
.Dv SO_SND .
.Ss Socket Destructor Callback
A kernel system can use the
.Fn sodtor_set
function to set a destructor for a socket.
The destructor is called when the socket is closed.
The destructor is called after the protocol close routine has completed.
The destructor can serve as a callback to initiate additional cleanup actions.
.Ss Socket I/O
The
.Fn soreceive

View File

@ -1101,6 +1101,8 @@ soclose(struct socket *so)
drop:
if (so->so_proto->pr_usrreqs->pru_close != NULL)
(*so->so_proto->pr_usrreqs->pru_close)(so);
if (so->so_dtor != NULL)
so->so_dtor(so);
SOCK_LOCK(so);
if ((listening = (so->so_options & SO_ACCEPTCONN))) {
@ -3812,6 +3814,17 @@ sodupsockaddr(const struct sockaddr *sa, int mflags)
return sa2;
}
/*
* Register per-socket destructor.
*/
void
sodtor_set(struct socket *so, so_dtor_t *func)
{
SOCK_LOCK_ASSERT(so);
so->so_dtor = func;
}
/*
* Register per-socket buffer upcalls.
*/

View File

@ -63,6 +63,7 @@ struct vnet;
* private data and error information.
*/
typedef int so_upcall_t(struct socket *, void *, int);
typedef void so_dtor_t(struct socket *);
struct socket;
@ -99,6 +100,7 @@ struct socket {
/* NB: generation count must not be first. */
so_gen_t so_gencnt; /* (h) generation count */
void *so_emuldata; /* (b) private data for emulators */
so_dtor_t *so_dtor; /* (b) optional destructor */
struct osd osd; /* Object Specific extensions */
/*
* so_fibnum, so_user_cookie and friends can be used to attach
@ -397,6 +399,7 @@ int soconnect2(struct socket *so1, struct socket *so2);
int socreate(int dom, struct socket **aso, int type, int proto,
struct ucred *cred, struct thread *td);
int sodisconnect(struct socket *so);
void sodtor_set(struct socket *, so_dtor_t *);
struct sockaddr *sodupsockaddr(const struct sockaddr *sa, int mflags);
void sofree(struct socket *so);
void sohasoutofband(struct socket *so);