Source-Changes-HG archive

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

[src/kqueue]: src/sys/kern add kqueue methods for filt_so*



details:   https://anonhg.NetBSD.org/src/rev/c3e46b9072a0
branches:  kqueue
changeset: 512355:c3e46b9072a0
user:      lukem <lukem%NetBSD.org@localhost>
date:      Tue Jul 10 13:48:47 2001 +0000

description:
add kqueue methods for filt_so*

diffstat:

 sys/kern/uipc_socket.c |  143 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 142 insertions(+), 1 deletions(-)

diffs (161 lines):

diff -r 4a1897f96241 -r c3e46b9072a0 sys/kern/uipc_socket.c
--- a/sys/kern/uipc_socket.c    Tue Jul 10 13:48:05 2001 +0000
+++ b/sys/kern/uipc_socket.c    Tue Jul 10 13:48:47 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uipc_socket.c,v 1.56 2001/04/13 23:30:10 thorpej Exp $ */
+/*     $NetBSD: uipc_socket.c,v 1.56.2.1 2001/07/10 13:48:47 lukem Exp $       */
 
 /*
  * Copyright (c) 1982, 1986, 1988, 1990, 1993
@@ -51,6 +51,20 @@
 #include <sys/signalvar.h>
 #include <sys/resourcevar.h>
 #include <sys/pool.h>
+#include <sys/event.h>
+
+static void    filt_sordetach(struct knote *kn);
+static int     filt_soread(struct knote *kn, long hint); 
+static void    filt_sowdetach(struct knote *kn);
+static int     filt_sowrite(struct knote *kn, long hint);
+static int     filt_solisten(struct knote *kn, long hint);
+
+static struct filterops solisten_filtops =
+       { 1, NULL, filt_sordetach, filt_solisten };
+struct filterops soread_filtops =
+       { 1, NULL, filt_sordetach, filt_soread };
+struct filterops sowrite_filtops =
+       { 1, NULL, filt_sowdetach, filt_sowrite };
 
 struct pool    socket_pool;
 
@@ -1108,3 +1122,130 @@
                psignal(p, SIGURG);
        selwakeup(&so->so_rcv.sb_sel);
 }
+
+
+int
+soo_kqfilter(struct file *fp, struct knote *kn)
+{
+       struct socket   *so;
+       struct sockbuf  *sb;
+       int             s;
+
+       so = (struct socket *)kn->kn_fp->f_data;
+       switch (kn->kn_filter) {
+       case EVFILT_READ:
+               if (so->so_options & SO_ACCEPTCONN)
+                       kn->kn_fop = &solisten_filtops;
+               else
+                       kn->kn_fop = &soread_filtops;
+               sb = &so->so_rcv;
+               break;
+       case EVFILT_WRITE:
+               kn->kn_fop = &sowrite_filtops;
+               sb = &so->so_snd;
+               break;
+       default:
+               return (1);
+       }
+       s = splnet();           /* XXXLUKEM: maybe splsoftnet() ? */
+       SLIST_INSERT_HEAD(&sb->sb_sel.si_klist, kn, kn_selnext);
+       sb->sb_flags |= SB_KNOTE;
+       splx(s);
+       return (0);
+}
+
+static void
+filt_sordetach(struct knote *kn)
+{
+       struct socket   *so;
+       int             s;
+
+       so = (struct socket *)kn->kn_fp->f_data;
+       s = splnet();           /* XXXLUKEM: maybe splsoftnet() ? */
+       SLIST_REMOVE(&so->so_rcv.sb_sel.si_klist, kn, knote, kn_selnext);
+       if (SLIST_EMPTY(&so->so_rcv.sb_sel.si_klist))
+               so->so_rcv.sb_flags &= ~SB_KNOTE;
+       splx(s);
+}
+
+/*ARGSUSED*/
+static int
+filt_soread(struct knote *kn, long hint)
+{
+       struct socket   *so;
+
+       so = (struct socket *)kn->kn_fp->f_data;
+       kn->kn_data = so->so_rcv.sb_cc;
+       if (so->so_state & SS_CANTRCVMORE) {
+               kn->kn_flags |= EV_EOF; 
+               kn->kn_fflags = so->so_error;
+               return (1);
+       }
+       if (so->so_error)       /* temporary udp error */
+               return (1);
+       if (kn->kn_sfflags & NOTE_LOWAT)
+               return (kn->kn_data >= kn->kn_sdata);
+       return (kn->kn_data >= so->so_rcv.sb_lowat);
+}
+
+static void
+filt_sowdetach(struct knote *kn)
+{
+       struct socket   *so;
+       int             s;
+
+       so = (struct socket *)kn->kn_fp->f_data;
+       s = splnet();           /* XXXLUKEM: maybe splsoftnet() ? */
+       SLIST_REMOVE(&so->so_snd.sb_sel.si_klist, kn, knote, kn_selnext);
+       if (SLIST_EMPTY(&so->so_snd.sb_sel.si_klist))
+               so->so_snd.sb_flags &= ~SB_KNOTE;
+       splx(s);
+}
+
+/*ARGSUSED*/
+static int
+filt_sowrite(struct knote *kn, long hint)
+{
+       struct socket   *so;
+
+       so = (struct socket *)kn->kn_fp->f_data;
+       kn->kn_data = sbspace(&so->so_snd);
+       if (so->so_state & SS_CANTSENDMORE) {
+               kn->kn_flags |= EV_EOF; 
+               kn->kn_fflags = so->so_error;
+               return (1);
+       }
+       if (so->so_error)       /* temporary udp error */
+               return (1);
+       if (((so->so_state & SS_ISCONNECTED) == 0) &&
+           (so->so_proto->pr_flags & PR_CONNREQUIRED))
+               return (0);
+       if (kn->kn_sfflags & NOTE_LOWAT)
+               return (kn->kn_data >= kn->kn_sdata);
+       return (kn->kn_data >= so->so_snd.sb_lowat);
+}
+
+/*ARGSUSED*/
+static int
+filt_solisten(struct knote *kn, long hint)
+{
+       struct socket   *so;
+
+       so = (struct socket *)kn->kn_fp->f_data;
+#if 0
+       /*
+        * XXXLUKEM:    this was freebsd's code. it appears that they
+        * XXXLUKEM:    modified the socket code to store the count
+        * XXXLUKEM:    of all connections in so_qlen, and separately
+        * XXXLUKEM:    track the number of incompletes in so_incqlen.
+        * XXXLUKEM:    as we appear to keep only completed connections
+        * XXXLUKEM:    on so_qlen we can just return that.
+        * XXXLUKEM:    that said, a socket guru should double check for me :)
+        */
+       kn->kn_data = so->so_qlen - so->so_incqlen;
+       return (! TAILQ_EMPTY(&so->so_comp));
+#else
+       kn->kn_data = so->so_qlen;
+       return (kn->kn_data > 0);
+#endif
+}



Home | Main Index | Thread Index | Old Index