diff options
author | dillon <dillon@FreeBSD.org> | 2001-11-17 03:07:11 +0000 |
---|---|---|
committer | dillon <dillon@FreeBSD.org> | 2001-11-17 03:07:11 +0000 |
commit | 86ed17d675cb503ddb3f71f8b6f7c3af530bb29a (patch) | |
tree | d5160b5791cda1a8cfbbcd3f5e1bd7ea97561c8f /sys/kern/uipc_socket.c | |
parent | fe91520d395f7879be049a289cbac3389fed1749 (diff) | |
download | FreeBSD-src-86ed17d675cb503ddb3f71f8b6f7c3af530bb29a.zip FreeBSD-src-86ed17d675cb503ddb3f71f8b6f7c3af530bb29a.tar.gz |
Give struct socket structures a ref counting interface similar to
vnodes. This will hopefully serve as a base from which we can
expand the MP code. We currently do not attempt to obtain any
mutex or SX locks, but the door is open to add them when we nail
down exactly how that part of it is going to work.
Diffstat (limited to 'sys/kern/uipc_socket.c')
-rw-r--r-- | sys/kern/uipc_socket.c | 33 |
1 files changed, 27 insertions, 6 deletions
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 10c8585..caae630c 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -91,6 +91,10 @@ SYSCTL_DECL(_kern_ipc); static int somaxconn = SOMAXCONN; SYSCTL_INT(_kern_ipc, KIPC_SOMAXCONN, somaxconn, CTLFLAG_RW, &somaxconn, 0, "Maximum pending socket connection queue size"); +static int numopensockets; +SYSCTL_INT(_kern_ipc, OID_AUTO, numopensockets, CTLFLAG_RD, + &numopensockets, 0, "Number of open sockets"); + /* * Socket operation routines. @@ -106,6 +110,8 @@ SYSCTL_INT(_kern_ipc, KIPC_SOMAXCONN, somaxconn, CTLFLAG_RW, * Note that it would probably be better to allocate socket * and PCB at the same time, but I'm not convinced that all * the protocols can be easily modified to do this. + * + * soalloc() returns a socket with a ref count of 0. */ struct socket * soalloc(waitok) @@ -119,11 +125,17 @@ soalloc(waitok) bzero(so, sizeof *so); so->so_gencnt = ++so_gencnt; so->so_zone = socket_zone; + /* sx_init(&so->so_sxlock, "socket sxlock"); */ TAILQ_INIT(&so->so_aiojobq); + ++numopensockets; } return so; } +/* + * socreate returns a socket with a ref count of 1. The socket should be + * closed with soclose(). + */ int socreate(dom, aso, type, proto, td) int dom; @@ -162,10 +174,11 @@ socreate(dom, aso, type, proto, td) so->so_type = type; so->so_cred = crhold(td->td_proc->p_ucred); so->so_proto = prp; + soref(so); error = (*prp->pr_usrreqs->pru_attach)(so, proto, td); if (error) { so->so_state |= SS_NOFDREF; - sofree(so); + sorele(so); return (error); } *aso = so; @@ -186,11 +199,11 @@ sobind(so, nam, td) return (error); } -void -sodealloc(so) - struct socket *so; +static void +sodealloc(struct socket *so) { + KASSERT(so->so_count == 0, ("sodealloc(): so_count %d", so->so_count)); so->so_gencnt = ++so_gencnt; if (so->so_rcv.sb_hiwat) (void)chgsbsize(so->so_cred->cr_uidinfo, @@ -210,7 +223,9 @@ sodealloc(so) } #endif crfree(so->so_cred); + /* sx_destroy(&so->so_sxlock); */ zfree(so->so_zone, so); + --numopensockets; } int @@ -242,6 +257,8 @@ sofree(so) { struct socket *head = so->so_head; + KASSERT(so->so_count == 0, ("socket %p so_count not 0", so)); + if (so->so_pcb || (so->so_state & SS_NOFDREF) == 0) return; if (head != NULL) { @@ -272,6 +289,10 @@ sofree(so) * Close a socket on last file table reference removal. * Initiate disconnect if connected. * Free socket when disconnect complete. + * + * This function will sorele() the socket. Note that soclose() may be + * called prior to the ref count reaching zero. The actual socket + * structure will not be freed until the ref count reaches zero. */ int soclose(so) @@ -329,7 +350,7 @@ discard: if (so->so_state & SS_NOFDREF) panic("soclose: NOFDREF"); so->so_state |= SS_NOFDREF; - sofree(so); + sorele(so); splx(s); return (error); } @@ -345,7 +366,7 @@ soabort(so) error = (*so->so_proto->pr_usrreqs->pru_abort)(so); if (error) { - sofree(so); + sotryfree(so); /* note: does not decrement the ref count */ return error; } return (0); |