summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/kern/uipc_socket.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2017-04-04 09:36:57 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2017-04-04 14:46:23 +0200
commitde8a76da2f374792594ce03a203b3f30e4889f6f (patch)
tree12b5e1e59358005c3c522955c08aee4795e4829c /freebsd/sys/kern/uipc_socket.c
parentEnable bridging by default (diff)
downloadrtems-libbsd-de8a76da2f374792594ce03a203b3f30e4889f6f.tar.bz2
Update to FreeBSD head 2017-04-04
Git mirror commit 642b174daddbd0efd9bb5f242c43f4ab4db6869f.
Diffstat (limited to 'freebsd/sys/kern/uipc_socket.c')
-rw-r--r--freebsd/sys/kern/uipc_socket.c77
1 files changed, 57 insertions, 20 deletions
diff --git a/freebsd/sys/kern/uipc_socket.c b/freebsd/sys/kern/uipc_socket.c
index 5f01844d..59a52115 100644
--- a/freebsd/sys/kern/uipc_socket.c
+++ b/freebsd/sys/kern/uipc_socket.c
@@ -165,18 +165,13 @@ static void filt_sordetach(struct knote *kn);
static int filt_soread(struct knote *kn, long hint);
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);
#ifdef __rtems__
static
#endif /* __rtems__ */
fo_kqfilter_t soo_kqfilter;
-static struct filterops solisten_filtops = {
- .f_isfd = 1,
- .f_detach = filt_sordetach,
- .f_event = filt_solisten,
-};
static struct filterops soread_filtops = {
.f_isfd = 1,
.f_detach = filt_sordetach,
@@ -187,6 +182,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 */
@@ -2714,6 +2714,26 @@ sosetopt(struct socket *so, struct sockopt *sopt)
#endif
break;
+ case SO_TS_CLOCK:
+ error = sooptcopyin(sopt, &optval, sizeof optval,
+ sizeof optval);
+ if (error)
+ goto bad;
+ if (optval < 0 || optval > SO_TS_CLOCK_MAX) {
+ error = EINVAL;
+ goto bad;
+ }
+ so->so_ts_clock = optval;
+ break;
+
+ case SO_MAX_PACING_RATE:
+ error = sooptcopyin(sopt, &val32, sizeof(val32),
+ sizeof(val32));
+ if (error)
+ goto bad;
+ so->so_max_pacing_rate = val32;
+ break;
+
default:
if (V_socket_hhh[HHOOK_SOCKET_OPT]->hhh_nhooks > 0)
error = hhook_run_socket(so, sopt,
@@ -2901,6 +2921,14 @@ integer:
optval = so->so_incqlen;
goto integer;
+ case SO_TS_CLOCK:
+ optval = so->so_ts_clock;
+ goto integer;
+
+ case SO_MAX_PACING_RATE:
+ optval = so->so_max_pacing_rate;
+ goto integer;
+
default:
if (V_socket_hhh[HHOOK_SOCKET_OPT]->hhh_nhooks > 0)
error = hhook_run_socket(so, sopt,
@@ -3108,16 +3136,17 @@ soo_kqfilter(struct file *fp, struct knote *kn)
switch (kn->kn_filter) {
case EVFILT_READ:
- if (so->so_options & SO_ACCEPTCONN)
- kn->kn_fop = &solisten_filtops;
- else
- kn->kn_fop = &soread_filtops;
+ kn->kn_fop = &soread_filtops;
sb = &so->so_rcv;
break;
case EVFILT_WRITE:
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);
}
@@ -3327,6 +3356,11 @@ filt_soread(struct knote *kn, long hint)
struct socket *so;
so = kn->kn_fp->f_data;
+ if (so->so_options & SO_ACCEPTCONN) {
+ kn->kn_data = so->so_qlen;
+ return (!TAILQ_EMPTY(&so->so_comp));
+
+ }
SOCKBUF_LOCK_ASSERT(&so->so_rcv);
kn->kn_data = sbavail(&so->so_rcv) - so->so_rcv.sb_ctl;
@@ -3339,11 +3373,9 @@ filt_soread(struct knote *kn, long hint)
if (kn->kn_sfflags & NOTE_LOWAT) {
if (kn->kn_data >= kn->kn_sdata)
- return 1;
- } else {
- if (sbavail(&so->so_rcv) >= so->so_rcv.sb_lowat)
- return 1;
- }
+ return (1);
+ } else if (sbavail(&so->so_rcv) >= so->so_rcv.sb_lowat)
+ return (1);
/* This hook returning non-zero indicates an event, not error */
return (hhook_run_socket(so, NULL, HHOOK_FILT_SOREAD));
@@ -3388,14 +3420,19 @@ filt_sowrite(struct knote *kn, long hint)
return (kn->kn_data >= so->so_snd.sb_lowat);
}
-/*ARGSUSED*/
static int
-filt_solisten(struct knote *kn, long hint)
+filt_soempty(struct knote *kn, long hint)
{
- struct socket *so = kn->kn_fp->f_data;
+ struct socket *so;
+
+ so = kn->kn_fp->f_data;
+ SOCKBUF_LOCK_ASSERT(&so->so_snd);
+ kn->kn_data = sbused(&so->so_snd);
- kn->kn_data = so->so_qlen;
- return (!TAILQ_EMPTY(&so->so_comp));
+ if (kn->kn_data == 0)
+ return (1);
+ else
+ return (0);
}
#ifndef __rtems__