Index: head/sys/kern/kern_event.c =================================================================== --- head/sys/kern/kern_event.c +++ head/sys/kern/kern_event.c @@ -344,6 +344,7 @@ { &null_filtops }, /* EVFILT_LIO */ { &user_filtops, 1 }, /* EVFILT_USER */ { &null_filtops }, /* EVFILT_SENDFILE */ + { &file_filtops, 1 }, /* EVFILT_EMPTY */ }; /* Index: head/sys/kern/uipc_socket.c =================================================================== --- head/sys/kern/uipc_socket.c +++ head/sys/kern/uipc_socket.c @@ -161,6 +161,7 @@ static int filt_sowrite(struct knote *kn, long hint); static int filt_solisten(struct knote *kn, long hint); static int inline hhook_run_socket(struct socket *so, void *hctx, int32_t h_id); +static int filt_soempty(struct knote *kn, long hint); fo_kqfilter_t soo_kqfilter; static struct filterops solisten_filtops = { @@ -178,6 +179,11 @@ .f_detach = filt_sowdetach, .f_event = filt_sowrite, }; +static struct filterops soempty_filtops = { + .f_isfd = 1, + .f_detach = filt_sowdetach, + .f_event = filt_soempty, +}; so_gen_t so_gencnt; /* generation count for sockets */ @@ -3083,6 +3089,10 @@ kn->kn_fop = &sowrite_filtops; sb = &so->so_snd; break; + case EVFILT_EMPTY: + kn->kn_fop = &soempty_filtops; + sb = &so->so_snd; + break; default: return (EINVAL); } @@ -3344,6 +3354,21 @@ return (kn->kn_data >= so->so_snd.sb_lowat); } +static int +filt_soempty(struct knote *kn, long hint) +{ + struct socket *so; + + so = kn->kn_fp->f_data; + SOCKBUF_LOCK_ASSERT(&so->so_snd); + kn->kn_data = sbused(&so->so_snd); + + if (kn->kn_data == 0) + return (1); + else + return (0); +} + /*ARGSUSED*/ static int filt_solisten(struct knote *kn, long hint) Index: head/sys/sys/event.h =================================================================== --- head/sys/sys/event.h +++ head/sys/sys/event.h @@ -43,7 +43,8 @@ #define EVFILT_LIO (-10) /* attached to lio requests */ #define EVFILT_USER (-11) /* User events */ #define EVFILT_SENDFILE (-12) /* attached to sendfile requests */ -#define EVFILT_SYSCOUNT 12 +#define EVFILT_EMPTY (-13) /* empty send socket buf */ +#define EVFILT_SYSCOUNT 13 #define EV_SET(kevp_, a, b, c, d, e, f) do { \ struct kevent *kevp = (kevp_); \