Module Name: src Committed By: rmind Date: Fri Oct 18 02:32:12 UTC 2013
Modified Files: src/sys/kern [rmind-smpnet]: uipc_socket.c src/sys/sys [rmind-smpnet]: socketvar.h Log Message: Add soref() and sounref(). To generate a diff of this commit: cvs rdiff -u -r1.215.4.2 -r1.215.4.3 src/sys/kern/uipc_socket.c cvs rdiff -u -r1.130.2.1 -r1.130.2.2 src/sys/sys/socketvar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/uipc_socket.c diff -u src/sys/kern/uipc_socket.c:1.215.4.2 src/sys/kern/uipc_socket.c:1.215.4.3 --- src/sys/kern/uipc_socket.c:1.215.4.2 Wed Aug 28 23:59:35 2013 +++ src/sys/kern/uipc_socket.c Fri Oct 18 02:32:12 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: uipc_socket.c,v 1.215.4.2 2013/08/28 23:59:35 rmind Exp $ */ +/* $NetBSD: uipc_socket.c,v 1.215.4.3 2013/10/18 02:32:12 rmind Exp $ */ /*- * Copyright (c) 2002, 2007, 2008, 2009 The NetBSD Foundation, Inc. @@ -71,7 +71,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.215.4.2 2013/08/28 23:59:35 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.215.4.3 2013/10/18 02:32:12 rmind Exp $"); #include "opt_compat_netbsd.h" #include "opt_sock_counters.h" @@ -528,6 +528,8 @@ socreate(int dom, struct socket **aso, i so = soget(true); so->so_type = type; so->so_proto = prp; + so->so_refcnt = 1; + so->so_send = sosend; so->so_receive = soreceive; #ifdef MBUFTRACE @@ -607,6 +609,21 @@ fsocreate(int domain, struct socket **so return error; } +void +soref(struct socket *so) +{ + atomic_inc_uint(&so->so_refcnt); +} + +void +sounref(struct socket *so) +{ + if (atomic_dec_uint_nv(&so->so_refcnt) > 0) { + return; + } + soput(so); +} + int sofamily(const struct socket *so) { @@ -661,7 +678,6 @@ solisten(struct socket *so, int backlog, void sofree(struct socket *so) { - u_int refs; KASSERT(solocked(so)); @@ -691,13 +707,13 @@ sofree(struct socket *so) KASSERT(!cv_has_waiters(&so->so_rcv.sb_cv)); KASSERT(!cv_has_waiters(&so->so_snd.sb_cv)); sorflush(so); - refs = so->so_aborting; /* XXX */ /* Remove acccept filter if one is present. */ if (so->so_accf != NULL) (void)accept_filt_clear(so); sounlock(so); - if (refs == 0) /* XXX */ - soput(so); + + /* Will soput() if the last reference. */ + sounref(so); } /* @@ -772,19 +788,23 @@ soabort(struct socket *so) { u_int refs; int error; - + KASSERT(solocked(so)); KASSERT(so->so_head == NULL); - so->so_aborting++; /* XXX */ + soref(so); error = (*so->so_proto->pr_usrreqs->pr_generic)(so, PRU_ABORT, NULL, NULL, NULL, NULL); - refs = --so->so_aborting; /* XXX */ - if (error || (refs == 0)) { + refs = so->so_refcnt; + sounref(so); + + /* XXX: Fix PRU_ABORT to behave consistently. */ + if (error || refs == 1) { sofree(so); } else { sounlock(so); } + sounref(so); return error; } Index: src/sys/sys/socketvar.h diff -u src/sys/sys/socketvar.h:1.130.2.1 src/sys/sys/socketvar.h:1.130.2.2 --- src/sys/sys/socketvar.h:1.130.2.1 Wed Aug 28 15:21:49 2013 +++ src/sys/sys/socketvar.h Fri Oct 18 02:32:12 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: socketvar.h,v 1.130.2.1 2013/08/28 15:21:49 rmind Exp $ */ +/* $NetBSD: socketvar.h,v 1.130.2.2 2013/10/18 02:32:12 rmind Exp $ */ /*- * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. @@ -128,7 +128,7 @@ struct socket { short so_options; /* from socket call, see socket.h */ u_short so_linger; /* time to linger while closing */ short so_state; /* internal state flags SS_*, below */ - int so_unused; /* used to be so_nbio */ + unsigned so_refcnt; /* reference count */ void *so_pcb; /* protocol control block */ const struct protosw *so_proto; /* protocol handle */ /* @@ -152,7 +152,7 @@ struct socket { short so_qlimit; /* max number queued connections */ short so_timeo; /* connection timeout */ u_short so_error; /* error affecting connection */ - u_short so_aborting; /* references from soabort() */ + u_short so_unused1; pid_t so_pgid; /* pgid for signals */ u_long so_oobmark; /* chars to oob mark */ struct sockbuf so_snd; /* send buffer */ @@ -298,6 +298,8 @@ int socreate(int, struct socket **, int, struct socket *); int fsocreate(int, struct socket **, int, int, int *); int sodisconnect(struct socket *); +void soref(struct socket *); +void sounref(struct socket *); void sofree(struct socket *); int sogetopt(struct socket *, struct sockopt *); void sohasoutofband(struct socket *);