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 {
|
||