Project

General

Profile

Submit #3135 » dfly_evfilt_recv.patch

tautolog, 05/25/2018 09:48 PM

View differences:

sys/kern/kern_event.c
&file_filtops, /* EVFILT_EXCEPT */
&user_filtops, /* EVFILT_USER */
&fs_filtops, /* EVFILT_FS */
&file_filtops, /* EVFILT_RECV */
&file_filtops, /* EVFILT_SEND */
};
static struct knote_cache_list knote_cache_lists[MAXCPU];
......
*/
fp = NULL;
kn->kn_sflags = kev->flags;
kn->kn_sfflags = kev->fflags;
kn->kn_sdata = kev->data;
kev->fflags = 0;
......
if (fops == &user_filtops) {
filt_usertouch(kn, kev, EVENT_REGISTER);
} else {
kn->kn_sflags = kev->flags;
kn->kn_sfflags = kev->fflags;
kn->kn_sdata = kev->data;
kn->kn_kevent.udata = kev->udata;
......
if (fops == &user_filtops) {
filt_usertouch(kn, kev, EVENT_REGISTER);
} else {
kn->kn_sflags = kev->flags;
kn->kn_sfflags = kev->fflags;
kn->kn_sdata = kev->data;
kn->kn_kevent.udata = kev->udata;
sys/kern/uipc_socket.c
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 int filt_sorecv(struct knote *kn, long hint);
static int filt_sosend(struct knote *kn, long hint);
static int soclose_sync(struct socket *so, int fflag);
static void soclose_fast(struct socket *so);
......
{ FILTEROP_ISFD|FILTEROP_MPSAFE, NULL, filt_sowdetach, filt_sowrite };
static struct filterops soexcept_filtops =
{ FILTEROP_ISFD|FILTEROP_MPSAFE, NULL, filt_sordetach, filt_soread };
static struct filterops sorecv_filtops =
{ FILTEROP_ISFD|FILTEROP_MPSAFE, NULL, filt_sordetach, filt_sorecv };
static struct filterops sosend_filtops =
{ FILTEROP_ISFD|FILTEROP_MPSAFE, NULL, filt_sowdetach, filt_sosend };
MALLOC_DEFINE(M_SOCKET, "socket", "socket struct");
MALLOC_DEFINE(M_SONAME, "soname", "socket name");
......
kn->kn_fop = &soexcept_filtops;
ssb = &so->so_rcv;
break;
case EVFILT_RECV:
kn->kn_fop = &sorecv_filtops;
ssb = &so->so_rcv;
break;
case EVFILT_SEND:
kn->kn_fop = &sosend_filtops;
ssb = &so->so_snd;
break;
default:
return (EOPNOTSUPP);
}
......
!TAILQ_EMPTY(&so->so_comp));
}
/*ARGSUSED*/
static int
filt_sorecv(struct knote *kn, long hint __unused)
{
struct socket *so = (struct socket *)kn->kn_fp->f_data;
int flags = 0;
int trigger = 0;
kn->kn_flags |= EV_DISPATCH;
kn->kn_data = so->so_rcv.ssb_cc;
if (kn->kn_sdata != kn->kn_data) {
kn->kn_sdata = kn->kn_data;
trigger = 1;
}
if (so->so_state & SS_CANTRCVMORE) {
/*
* Only set NODATA if all data has been exhausted.
*/
if (kn->kn_data == 0)
flags |= EV_NODATA;
flags |= EV_EOF;
}
kn->kn_flags |= flags;
if ((kn->kn_sflags & kn->kn_flags) != kn->kn_flags) {
kn->kn_sflags = kn->kn_flags;
trigger = 1;
}
kn->kn_fflags = so->so_error;
if (kn->kn_sfflags != kn->kn_fflags) {
kn->kn_sfflags = kn->kn_fflags;
trigger = 1;
}
if (trigger && kn->kn_status & KN_DISABLED) {
kn->kn_status &= ~KN_DISABLED;
}
return 1;
}
static void
filt_sowdetach(struct knote *kn)
{
......
return (kn->kn_data >= so->so_snd.ssb_lowat);
}
/*ARGSUSED*/
static int
filt_sosend(struct knote *kn, long hint __unused)
{
struct socket *so = (struct socket *)kn->kn_fp->f_data;
int flags = 0;
int trigger = 0;
kn->kn_flags |= EV_DISPATCH;
if (((so->so_state & SS_ISCONNECTED) == 0) &&
(so->so_proto->pr_flags & PR_CONNREQUIRED))
return (0);
if (so->so_snd.ssb_flags & SSB_PREALLOC) {
kn->kn_data = ssb_space_prealloc(&so->so_snd);
} else {
kn->kn_data = ssb_space(&so->so_snd);
}
if (kn->kn_sdata != kn->kn_data) {
kn->kn_sdata = kn->kn_data;
trigger = 1;
}
if (so->so_state & SS_CANTSENDMORE) {
flags |= (EV_EOF | EV_NODATA);
}
kn->kn_flags |= flags;
if ((kn->kn_sflags & kn->kn_flags) != kn->kn_flags) {
kn->kn_sflags = kn->kn_flags;
trigger = 1;
}
kn->kn_fflags = so->so_error;
if (kn->kn_sfflags != kn->kn_fflags) {
kn->kn_sfflags = kn->kn_fflags;
trigger = 1;
}
if (trigger && kn->kn_status & KN_DISABLED) {
kn->kn_status &= ~KN_DISABLED;
}
return 1;
}
/*ARGSUSED*/
static int
filt_solisten(struct knote *kn, long hint __unused)
sys/sys/event.h
#define EVFILT_EXCEPT (-8) /* exceptional conditions */
#define EVFILT_USER (-9) /* user events */
#define EVFILT_FS (-10) /* filesystem events */
#define EVFILT_RECV (-11) /* socket recv buffer */
#define EVFILT_SEND (-12) /* socket send buffer */
#define EVFILT_MARKER 0xF /* placemarker for tailq */
#define EVFILT_SYSCOUNT 10
#define EVFILT_SYSCOUNT 12
#define EV_SET(kevp_, a, b, c, d, e, f) do { \
struct kevent *kevp = (kevp_); \
......
struct kqueue *kn_kq; /* which queue we are on */
struct kevent kn_kevent;
int kn_status;
int kn_sflags; /* saved flags */
int kn_sfflags; /* saved filter flags */
intptr_t kn_sdata; /* saved data field */
union {
(1-1/2)