diff options
author | Hiren Panchasara <hiren@FreeBSD.org> | 2017-01-16 08:25:33 +0000 |
---|---|---|
committer | Hiren Panchasara <hiren@FreeBSD.org> | 2017-01-16 08:25:33 +0000 |
commit | 7d03ff1fe9cbc4b5a3fcc5423bfa4cc11389b78b (patch) | |
tree | 430d5e9dd5c233119fa3f0b581ab4c7f77d6f9b7 /sys/kern/uipc_socket.c | |
parent | 488b4e7e68f62c6b71c290c7547e8252afaa8329 (diff) | |
download | src-7d03ff1fe9cbc4b5a3fcc5423bfa4cc11389b78b.tar.gz src-7d03ff1fe9cbc4b5a3fcc5423bfa4cc11389b78b.zip |
Add kevent EVFILT_EMPTY for notification when a client has received all data
i.e. everything outstanding has been acked.
Reviewed by: bz, gnn (previous version)
MFC after: 3 days
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D9150
Notes
Notes:
svn path=/head/; revision=312277
Diffstat (limited to 'sys/kern/uipc_socket.c')
-rw-r--r-- | sys/kern/uipc_socket.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 23910c5bc1d3..f08fc9f1a7d8 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -161,6 +161,7 @@ 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 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 @@ static struct filterops sowrite_filtops = { .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 @@ soo_kqfilter(struct file *fp, struct knote *kn) 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 @@ filt_sowrite(struct knote *kn, long hint) 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) |