aboutsummaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorHiren Panchasara <hiren@FreeBSD.org>2017-01-16 08:25:33 +0000
committerHiren Panchasara <hiren@FreeBSD.org>2017-01-16 08:25:33 +0000
commit7d03ff1fe9cbc4b5a3fcc5423bfa4cc11389b78b (patch)
tree430d5e9dd5c233119fa3f0b581ab4c7f77d6f9b7 /sys/kern
parent488b4e7e68f62c6b71c290c7547e8252afaa8329 (diff)
downloadsrc-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')
-rw-r--r--sys/kern/kern_event.c1
-rw-r--r--sys/kern/uipc_socket.c25
2 files changed, 26 insertions, 0 deletions
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index f9ee7b1103db..4473d16230bf 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -344,6 +344,7 @@ static struct {
{ &null_filtops }, /* EVFILT_LIO */
{ &user_filtops, 1 }, /* EVFILT_USER */
{ &null_filtops }, /* EVFILT_SENDFILE */
+ { &file_filtops, 1 }, /* EVFILT_EMPTY */
};
/*
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)