Revamp the initial lwkt_abortmsg() support to normalize the abstraction. Now
[dragonfly.git] / sys / kern / uipc_socket2.c
index a5b737d..f6525a9 100644 (file)
@@ -32,6 +32,7 @@
  *
  *     @(#)uipc_socket2.c      8.1 (Berkeley) 6/10/93
  * $FreeBSD: src/sys/kern/uipc_socket2.c,v 1.55.2.17 2002/08/31 19:04:55 dwmalone Exp $
+ * $DragonFly: src/sys/kern/uipc_socket2.c,v 1.10 2004/04/20 01:52:22 dillon Exp $
  */
 
 #include "opt_param.h"
@@ -53,6 +54,9 @@
 #include <sys/aio.h> /* for aio_swake proto */
 #include <sys/event.h>
 
+#include <sys/thread2.h>
+#include <sys/msgport2.h>
+
 int    maxsockets;
 
 /*
@@ -97,7 +101,7 @@ static       u_long sb_efficiency = 8;       /* parameter for sbreserve() */
 
 void
 soisconnecting(so)
-       register struct socket *so;
+       struct socket *so;
 {
 
        so->so_state &= ~(SS_ISCONNECTED|SS_ISDISCONNECTING);
@@ -138,7 +142,7 @@ soisconnected(so)
 
 void
 soisdisconnecting(so)
-       register struct socket *so;
+       struct socket *so;
 {
 
        so->so_state &= ~SS_ISCONNECTING;
@@ -150,7 +154,7 @@ soisdisconnecting(so)
 
 void
 soisdisconnected(so)
-       register struct socket *so;
+       struct socket *so;
 {
 
        so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
@@ -170,21 +174,10 @@ soisdisconnected(so)
  * Connstatus may be 0, or SO_ISCONFIRMING, or SO_ISCONNECTED.
  */
 struct socket *
-sonewconn(head, connstatus)
-       register struct socket *head;
-       int connstatus;
-{
-
-       return (sonewconn3(head, connstatus, NULL));
-}
-
-struct socket *
-sonewconn3(head, connstatus, p)
-       register struct socket *head;
-       int connstatus;
-       struct proc *p;
+sonewconn(struct socket *head, int connstatus)
 {
-       register struct socket *so;
+       struct socket *so;
+       struct pru_attach_info ai;
 
        if (head->so_qlen > 3 * head->so_qlimit / 2)
                return ((struct socket *)0);
@@ -200,10 +193,13 @@ sonewconn3(head, connstatus, p)
        so->so_state = head->so_state | SS_NOFDREF;
        so->so_proto = head->so_proto;
        so->so_timeo = head->so_timeo;
-       so->so_cred = p ? p->p_ucred : head->so_cred;
-       crhold(so->so_cred);
-       if (soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat) ||
-           (*so->so_proto->pr_usrreqs->pru_attach)(so, 0, NULL)) {
+       so->so_cred = crhold(head->so_cred);
+       ai.sb_rlimit = NULL;
+       ai.p_ucred = NULL;
+       ai.fd_rdir = NULL;              /* jail code cruft XXX JH */
+       if (soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat, NULL) ||
+           /* Directly call function since we're already at protocol level. */
+           (*so->so_proto->pr_usrreqs->pru_attach)(so, 0, &ai)) {
                sodealloc(so);
                return ((struct socket *)0);
        }
@@ -268,8 +264,9 @@ sbwait(sb)
 
        sb->sb_flags |= SB_WAIT;
        return (tsleep((caddr_t)&sb->sb_cc,
-           (sb->sb_flags & SB_NOINTR) ? PSOCK : PSOCK | PCATCH, "sbwait",
-           sb->sb_timeo));
+                       ((sb->sb_flags & SB_NOINTR) ? 0 : PCATCH),
+                       "sbwait",
+                       sb->sb_timeo));
 }
 
 /*
@@ -278,15 +275,15 @@ sbwait(sb)
  */
 int
 sb_lock(sb)
-       register struct sockbuf *sb;
+       struct sockbuf *sb;
 {
        int error;
 
        while (sb->sb_flags & SB_LOCK) {
                sb->sb_flags |= SB_WANT;
                error = tsleep((caddr_t)&sb->sb_flags,
-                   (sb->sb_flags & SB_NOINTR) ? PSOCK : PSOCK|PCATCH,
-                   "sblock", 0);
+                           ((sb->sb_flags & SB_NOINTR) ? 0 : PCATCH),
+                           "sblock", 0);
                if (error)
                        return (error);
        }
@@ -295,16 +292,17 @@ sb_lock(sb)
 }
 
 /*
- * Wakeup processes waiting on a socket buffer.
- * Do asynchronous notification via SIGIO
- * if the socket has the SS_ASYNC flag set.
+ * Wakeup processes waiting on a socket buffer.  Do asynchronous notification
+ * via SIGIO if the socket has the SS_ASYNC flag set.
  */
 void
 sowakeup(so, sb)
-       register struct socket *so;
-       register struct sockbuf *sb;
+       struct socket *so;
+       struct sockbuf *sb;
 {
-       selwakeup(&sb->sb_sel);
+       struct selinfo *selinfo = &sb->sb_sel;
+
+       selwakeup(selinfo);
        sb->sb_flags &= ~SB_SEL;
        if (sb->sb_flags & SB_WAIT) {
                sb->sb_flags &= ~SB_WAIT;
@@ -316,7 +314,20 @@ sowakeup(so, sb)
                (*so->so_upcall)(so, so->so_upcallarg, M_DONTWAIT);
        if (sb->sb_flags & SB_AIO)
                aio_swake(so, sb);
-       KNOTE(&sb->sb_sel.si_note, 0);
+       KNOTE(&selinfo->si_note, 0);
+       if (sb->sb_flags & SB_MEVENT) {
+               struct netmsg_so_notify *msg, *nmsg;
+
+               TAILQ_FOREACH_MUTABLE(msg, &selinfo->si_mlist, nm_list, nmsg) {
+                       if (msg->nm_predicate((struct netmsg *)msg)) {
+                               TAILQ_REMOVE(&selinfo->si_mlist, msg, nm_list);
+                               lwkt_replymsg(&msg->nm_lmsg, 
+                                               msg->nm_lmsg.ms_error);
+                       }
+               }
+               if (TAILQ_EMPTY(&sb->sb_sel.si_mlist))
+                       sb->sb_flags &= ~SB_MEVENT;
+       }
 }
 
 /*
@@ -352,15 +363,11 @@ sowakeup(so, sb)
  */
 
 int
-soreserve(so, sndcc, rcvcc)
-       register struct socket *so;
-       u_long sndcc, rcvcc;
+soreserve(struct socket *so, u_long sndcc, u_long rcvcc, struct rlimit *rl)
 {
-       struct proc *p = curproc;
-
-       if (sbreserve(&so->so_snd, sndcc, so, p) == 0)
+       if (sbreserve(&so->so_snd, sndcc, so, rl) == 0)
                goto bad;
-       if (sbreserve(&so->so_rcv, rcvcc, so, p) == 0)
+       if (sbreserve(&so->so_rcv, rcvcc, so, rl) == 0)
                goto bad2;
        if (so->so_rcv.sb_lowat == 0)
                so->so_rcv.sb_lowat = 1;
@@ -401,21 +408,17 @@ sysctl_handle_sb_max(SYSCTL_HANDLER_ARGS)
  * if buffering efficiency is near the normal case.
  */
 int
-sbreserve(sb, cc, so, p)
-       struct sockbuf *sb;
-       u_long cc;
-       struct socket *so;
-       struct proc *p;
+sbreserve(struct sockbuf *sb, u_long cc, struct socket *so, struct rlimit *rl)
 {
 
        /*
-        * p will only be NULL when we're in an interrupt
-        * (e.g. in tcp_input())
+        * rl will only be NULL when we're in an interrupt (eg, in tcp_input)
+        * or when called from netgraph (ie, ngd_attach)
         */
        if (cc > sb_max_adj)
                return (0);
        if (!chgsbsize(so->so_cred->cr_uidinfo, &sb->sb_hiwat, cc,
-           p ? p->p_rlimit[RLIMIT_SBSIZE].rlim_cur : RLIM_INFINITY)) {
+                      rl ? rl->rlim_cur : RLIM_INFINITY)) {
                return (0);
        }
        sb->sb_mbmax = min(cc * sb_efficiency, sb_max);
@@ -475,7 +478,7 @@ sbappend(sb, m)
        struct sockbuf *sb;
        struct mbuf *m;
 {
-       register struct mbuf *n;
+       struct mbuf *n;
 
        if (m == 0)
                return;
@@ -496,11 +499,11 @@ sbappend(sb, m)
 #ifdef SOCKBUF_DEBUG
 void
 sbcheck(sb)
-       register struct sockbuf *sb;
+       struct sockbuf *sb;
 {
-       register struct mbuf *m;
-       register struct mbuf *n = 0;
-       register u_long len = 0, mbcnt = 0;
+       struct mbuf *m;
+       struct mbuf *n = 0;
+       u_long len = 0, mbcnt = 0;
 
        for (m = sb->sb_mb; m; m = n) {
            n = m->m_nextpkt;
@@ -525,10 +528,10 @@ sbcheck(sb)
  */
 void
 sbappendrecord(sb, m0)
-       register struct sockbuf *sb;
-       register struct mbuf *m0;
+       struct sockbuf *sb;
+       struct mbuf *m0;
 {
-       register struct mbuf *m;
+       struct mbuf *m;
 
        if (m0 == 0)
                return;
@@ -561,11 +564,11 @@ sbappendrecord(sb, m0)
  */
 void
 sbinsertoob(sb, m0)
-       register struct sockbuf *sb;
-       register struct mbuf *m0;
+       struct sockbuf *sb;
+       struct mbuf *m0;
 {
-       register struct mbuf *m;
-       register struct mbuf **mp;
+       struct mbuf *m;
+       struct mbuf **mp;
 
        if (m0 == 0)
                return;
@@ -608,15 +611,16 @@ sbinsertoob(sb, m0)
  */
 int
 sbappendaddr(sb, asa, m0, control)
-       register struct sockbuf *sb;
+       struct sockbuf *sb;
        struct sockaddr *asa;
        struct mbuf *m0, *control;
 {
-       register struct mbuf *m, *n;
+       struct mbuf *m, *n;
        int space = asa->sa_len;
 
-if (m0 && (m0->m_flags & M_PKTHDR) == 0)
-panic("sbappendaddr");
+       if (m0 && (m0->m_flags & M_PKTHDR) == 0)
+               panic("sbappendaddr");
+
        if (m0)
                space += m0->m_pkthdr.len;
        for (n = control; n; n = n->m_next) {
@@ -655,7 +659,7 @@ sbappendcontrol(sb, m0, control)
        struct sockbuf *sb;
        struct mbuf *control, *m0;
 {
-       register struct mbuf *m, *n;
+       struct mbuf *m, *n;
        int space = 0;
 
        if (control == 0)
@@ -690,11 +694,11 @@ sbappendcontrol(sb, m0, control)
  */
 void
 sbcompress(sb, m, n)
-       register struct sockbuf *sb;
-       register struct mbuf *m, *n;
+       struct sockbuf *sb;
+       struct mbuf *m, *n;
 {
-       register int eor = 0;
-       register struct mbuf *o;
+       int eor = 0;
+       struct mbuf *o;
 
        while (m) {
                eor |= m->m_flags & M_EOR;
@@ -741,7 +745,7 @@ sbcompress(sb, m, n)
  */
 void
 sbflush(sb)
-       register struct sockbuf *sb;
+       struct sockbuf *sb;
 {
 
        if (sb->sb_flags & SB_LOCK)
@@ -764,10 +768,10 @@ sbflush(sb)
  */
 void
 sbdrop(sb, len)
-       register struct sockbuf *sb;
-       register int len;
+       struct sockbuf *sb;
+       int len;
 {
-       register struct mbuf *m;
+       struct mbuf *m;
        struct mbuf *next;
 
        next = (m = sb->sb_mb) ? m->m_nextpkt : 0;
@@ -806,9 +810,9 @@ sbdrop(sb, len)
  */
 void
 sbdroprecord(sb)
-       register struct sockbuf *sb;
+       struct sockbuf *sb;
 {
-       register struct mbuf *m;
+       struct mbuf *m;
 
        m = sb->sb_mb;
        if (m) {
@@ -827,10 +831,10 @@ sbdroprecord(sb)
 struct mbuf *
 sbcreatecontrol(p, size, type, level)
        caddr_t p;
-       register int size;
+       int size;
        int type, level;
 {
-       register struct cmsghdr *cp;
+       struct cmsghdr *cp;
        struct mbuf *m;
 
        if (CMSG_SPACE((u_int)size) > MCLBYTES)
@@ -868,7 +872,7 @@ pru_accept_notsupp(struct socket *so, struct sockaddr **nam)
 }
 
 int
-pru_connect_notsupp(struct socket *so, struct sockaddr *nam, struct proc *p)
+pru_connect_notsupp(struct socket *so, struct sockaddr *nam, struct thread *td)
 {
        return EOPNOTSUPP;
 }
@@ -881,13 +885,13 @@ pru_connect2_notsupp(struct socket *so1, struct socket *so2)
 
 int
 pru_control_notsupp(struct socket *so, u_long cmd, caddr_t data,
-                   struct ifnet *ifp, struct proc *p)
+                   struct ifnet *ifp, struct thread *td)
 {
        return EOPNOTSUPP;
 }
 
 int
-pru_listen_notsupp(struct socket *so, struct proc *p)
+pru_listen_notsupp(struct socket *so, struct thread *td)
 {
        return EOPNOTSUPP;
 }