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 *);