Submit #3135 » dfly_evfilt_recv.patch
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 {
|