tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Patch: add directional argument to socket upcall handler



The attached patch adds an argument to socket upcall handlers, so
they can tell whether they've been called because the socket is
ready for input or output.  This significantly eases the way for
in-kernel code that needs to interact with socket flow control,
such as splice() or things of its ilk.  I think it might also make
it possible to improve the wakeup mechanism in the NFS code, which
seems to care whether the socket's come ready for read or write
when adjusting various timers and handling errors.

Hastily ported forward from netbsd-5 to -current -- compiles, and
appears to work (works fine in our netbsd-5 tree).

Comments?

-- 
Thor Lancelot Simon
Coyote Point Systems, Inc.                      <tls%coyotepoint.com@localhost>
Millerton, NY, USA
Index: kern/uipc_socket2.c
===================================================================
RCS file: /cvsroot/src/sys/kern/uipc_socket2.c,v
retrieving revision 1.103
diff -u -r1.103 uipc_socket2.c
--- kern/uipc_socket2.c 24 Jul 2009 01:09:49 -0000      1.103
+++ kern/uipc_socket2.c 25 Aug 2009 14:32:38 -0000
@@ -190,7 +190,8 @@
                        so->so_upcallarg = head->so_accf->so_accept_filter_arg;
                        so->so_rcv.sb_flags |= SB_UPCALL;
                        so->so_options &= ~SO_ACCEPTFILTER;
-                       (*so->so_upcall)(so, so->so_upcallarg, M_DONTWAIT);
+                       (*so->so_upcall)(so, so->so_upcallarg,
+                                        POLLIN|POLLRDNORM, M_DONTWAIT);
                }
        } else {
                cv_broadcast(&so->so_cv);
@@ -472,7 +473,7 @@
        if (sb->sb_flags & SB_ASYNC)
                fownsignal(so->so_pgid, SIGIO, code, band, so);
        if (sb->sb_flags & SB_UPCALL)
-               (*so->so_upcall)(so, so->so_upcallarg, M_DONTWAIT);
+               (*so->so_upcall)(so, so->so_upcallarg, band, M_DONTWAIT);
 }
 
 /*
Index: net/if_gre.c
===================================================================
RCS file: /cvsroot/src/sys/net/if_gre.c,v
retrieving revision 1.140
diff -u -r1.140 if_gre.c
--- net/if_gre.c        28 Apr 2009 23:05:25 -0000      1.140
+++ net/if_gre.c        25 Aug 2009 14:32:39 -0000
@@ -419,7 +419,7 @@
 }
 
 static void
-gre_receive(struct socket *so, void *arg, int waitflag)
+gre_receive(struct socket *so, void *arg, int events, int waitflag)
 {
        struct gre_softc *sc = (struct gre_softc *)arg;
        int rc;
Index: netinet/accf_data.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/accf_data.c,v
retrieving revision 1.5
diff -u -r1.5 accf_data.c
--- netinet/accf_data.c 20 Nov 2008 10:22:11 -0000      1.5
+++ netinet/accf_data.c 25 Aug 2009 14:32:39 -0000
@@ -44,7 +44,7 @@
 
 /* accept filter that holds a socket until data arrives */
 
-static void    sohasdata(struct socket *so, void *arg, int waitflag);
+static void    sohasdata(struct socket *so, void *arg, int events, int 
waitflag);
 
 static struct accept_filter accf_data_filter = {
        .accf_name = "dataready",
@@ -77,7 +77,7 @@
 }
 
 static void
-sohasdata(struct socket *so, void *arg, int waitflag)
+sohasdata(struct socket *so, void *arg, int events, int waitflag)
 {
 
        if (!soreadable(so))
Index: netinet/accf_http.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/accf_http.c,v
retrieving revision 1.6
diff -u -r1.6 accf_http.c
--- netinet/accf_http.c 21 Nov 2008 16:08:57 -0000      1.6
+++ netinet/accf_http.c 25 Aug 2009 14:32:40 -0000
@@ -46,11 +46,11 @@
 MODULE(MODULE_CLASS_MISC, accf_httpready, NULL);
 
 /* check for GET/HEAD */
-static void sohashttpget(struct socket *so, void *arg, int waitflag);
+static void sohashttpget(struct socket *so, void *arg, int events, int 
waitflag);
 /* check for HTTP/1.0 or HTTP/1.1 */
-static void soparsehttpvers(struct socket *so, void *arg, int waitflag);
+static void soparsehttpvers(struct socket *so, void *arg, int events, int 
waitflag);
 /* check for end of HTTP/1.x request */
-static void soishttpconnected(struct socket *so, void *arg, int waitflag);
+static void soishttpconnected(struct socket *so, void *arg, int events, int 
waitflag);
 /* strcmp on an mbuf chain */
 static int mbufstrcmp(struct mbuf *m, struct mbuf *npkt, int offset, const 
char *cmp);
 /* strncmp on an mbuf chain */
@@ -221,7 +221,7 @@
        } while(0)
 
 static void
-sohashttpget(struct socket *so, void *arg, int waitflag)
+sohashttpget(struct socket *so, void *arg, int events, int waitflag)
 {
 
        if ((so->so_state & SS_CANTRCVMORE) == 0 && !sbfull(&so->so_rcv)) {
@@ -255,9 +255,9 @@
                if (mbufstrcmp(m, m->m_nextpkt, 1, cmp) == 1) {
                        DPRINT("mbufstrcmp ok");
                        if (parse_http_version == 0)
-                               soishttpconnected(so, arg, waitflag);
+                               soishttpconnected(so, arg, events, waitflag);
                        else
-                               soparsehttpvers(so, arg, waitflag);
+                               soparsehttpvers(so, arg, events, waitflag);
                        return;
                }
                DPRINT("mbufstrcmp bad");
@@ -272,7 +272,7 @@
 }
 
 static void
-soparsehttpvers(struct socket *so, void *arg, int waitflag)
+soparsehttpvers(struct socket *so, void *arg, int events, int waitflag)
 {
        struct mbuf *m, *n;
        int     i, cc, spaces, inspaces;
@@ -325,7 +325,7 @@
                                            mbufstrcmp(m, n, i, "HTTP/1.1")) {
                                                DPRINT("ok");
                                                soishttpconnected(so,
-                                                   arg, waitflag);
+                                                   arg, events, waitflag);
                                                return;
                                        } else {
                                                DPRINT("bad");
@@ -357,7 +357,7 @@
 #define NCHRS 3
 
 static void
-soishttpconnected(struct socket *so, void *arg, int waitflag)
+soishttpconnected(struct socket *so, void *arg, int events, int waitflag)
 {
        char a, b, c;
        struct mbuf *m, *n;
Index: netsmb/smb_trantcp.c
===================================================================
RCS file: /cvsroot/src/sys/netsmb/smb_trantcp.c,v
retrieving revision 1.42
diff -u -r1.42 smb_trantcp.c
--- netsmb/smb_trantcp.c        29 Mar 2009 19:21:20 -0000      1.42
+++ netsmb/smb_trantcp.c        25 Aug 2009 14:32:40 -0000
@@ -127,7 +127,7 @@
 }
 
 static void
-nb_upcall(struct socket *so, void *arg, int waitflag)
+nb_upcall(struct socket *so, void *arg, int events, int waitflag)
 {
        struct nbpcb *nbp = (void *)arg;
 
Index: nfs/nfs_srvsocket.c
===================================================================
RCS file: /cvsroot/src/sys/nfs/nfs_srvsocket.c,v
retrieving revision 1.3
diff -u -r1.3 nfs_srvsocket.c
--- nfs/nfs_srvsocket.c 14 Mar 2009 15:36:24 -0000      1.3
+++ nfs/nfs_srvsocket.c 25 Aug 2009 14:32:41 -0000
@@ -110,7 +110,7 @@
  * The void *arg is a pointer to the "struct nfssvc_sock".
  */
 void
-nfsrv_soupcall(struct socket *so, void *arg, int waitflag)
+nfsrv_soupcall(struct socket *so, void *arg, int events, int waitflag)
 {
        struct nfssvc_sock *slp = (struct nfssvc_sock *)arg;
 
Index: sys/socketvar.h
===================================================================
RCS file: /cvsroot/src/sys/sys/socketvar.h,v
retrieving revision 1.119
diff -u -r1.119 socketvar.h
--- sys/socketvar.h     4 Apr 2009 10:12:52 -0000       1.119
+++ sys/socketvar.h     25 Aug 2009 14:32:42 -0000
@@ -159,7 +159,7 @@
        struct sockbuf  so_rcv;         /* receive buffer */
 
        void            *so_internal;   /* Space for svr4 stream data */
-       void            (*so_upcall) (struct socket *, void *, int);
+       void            (*so_upcall) (struct socket *, void *, int, int);
        void *          so_upcallarg;   /* Arg for above */
        int             (*so_send) (struct socket *, struct mbuf *,
                                        struct uio *, struct mbuf *,
@@ -214,11 +214,11 @@
 struct accept_filter {
        char    accf_name[16];
        void    (*accf_callback)
-               (struct socket *so, void *arg, int waitflag);
+               (struct socket *, void *, int, int);
        void *  (*accf_create)
-               (struct socket *so, char *arg);
+               (struct socket *, char *);
        void    (*accf_destroy)
-               (struct socket *so);
+               (struct socket *);
        LIST_ENTRY(accept_filter) accf_next;
        u_int   accf_refcnt;
 };


Home | Main Index | Thread Index | Old Index