Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/uipc_socket.c
Show First 20 Lines • Show All 155 Lines • ▼ Show 20 Lines | static int soreceive_rcvoob(struct socket *so, struct uio *uio, | ||||
int flags); | int flags); | ||||
static void filt_sordetach(struct knote *kn); | static void filt_sordetach(struct knote *kn); | ||||
static int filt_soread(struct knote *kn, long hint); | static int filt_soread(struct knote *kn, long hint); | ||||
static void filt_sowdetach(struct knote *kn); | static void filt_sowdetach(struct knote *kn); | ||||
static int filt_sowrite(struct knote *kn, long hint); | static int filt_sowrite(struct knote *kn, long hint); | ||||
static int filt_solisten(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 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; | fo_kqfilter_t soo_kqfilter; | ||||
static struct filterops solisten_filtops = { | static struct filterops solisten_filtops = { | ||||
.f_isfd = 1, | .f_isfd = 1, | ||||
.f_detach = filt_sordetach, | .f_detach = filt_sordetach, | ||||
.f_event = filt_solisten, | .f_event = filt_solisten, | ||||
}; | }; | ||||
static struct filterops soread_filtops = { | static struct filterops soread_filtops = { | ||||
.f_isfd = 1, | .f_isfd = 1, | ||||
.f_detach = filt_sordetach, | .f_detach = filt_sordetach, | ||||
.f_event = filt_soread, | .f_event = filt_soread, | ||||
}; | }; | ||||
static struct filterops sowrite_filtops = { | static struct filterops sowrite_filtops = { | ||||
.f_isfd = 1, | .f_isfd = 1, | ||||
.f_detach = filt_sowdetach, | .f_detach = filt_sowdetach, | ||||
.f_event = filt_sowrite, | .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 */ | so_gen_t so_gencnt; /* generation count for sockets */ | ||||
MALLOC_DEFINE(M_SONAME, "soname", "socket name"); | MALLOC_DEFINE(M_SONAME, "soname", "socket name"); | ||||
MALLOC_DEFINE(M_PCB, "pcb", "protocol control block"); | MALLOC_DEFINE(M_PCB, "pcb", "protocol control block"); | ||||
#define VNET_SO_ASSERT(so) \ | #define VNET_SO_ASSERT(so) \ | ||||
VNET_ASSERT(curvnet != NULL, \ | VNET_ASSERT(curvnet != NULL, \ | ||||
▲ Show 20 Lines • Show All 2,889 Lines • ▼ Show 20 Lines | case EVFILT_READ: | ||||
else | else | ||||
kn->kn_fop = &soread_filtops; | kn->kn_fop = &soread_filtops; | ||||
sb = &so->so_rcv; | sb = &so->so_rcv; | ||||
break; | break; | ||||
case EVFILT_WRITE: | case EVFILT_WRITE: | ||||
kn->kn_fop = &sowrite_filtops; | kn->kn_fop = &sowrite_filtops; | ||||
sb = &so->so_snd; | sb = &so->so_snd; | ||||
break; | break; | ||||
case EVFILT_EMPTY: | |||||
kn->kn_fop = &soempty_filtops; | |||||
sb = &so->so_snd; | |||||
break; | |||||
default: | default: | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
SOCKBUF_LOCK(sb); | SOCKBUF_LOCK(sb); | ||||
knlist_add(&sb->sb_sel.si_note, kn, 1); | knlist_add(&sb->sb_sel.si_note, kn, 1); | ||||
sb->sb_flags |= SB_KNOTE; | sb->sb_flags |= SB_KNOTE; | ||||
SOCKBUF_UNLOCK(sb); | SOCKBUF_UNLOCK(sb); | ||||
▲ Show 20 Lines • Show All 243 Lines • ▼ Show 20 Lines | if (so->so_snd.sb_state & SBS_CANTSENDMORE) { | ||||
return (1); | return (1); | ||||
else if (((so->so_state & SS_ISCONNECTED) == 0) && | else if (((so->so_state & SS_ISCONNECTED) == 0) && | ||||
(so->so_proto->pr_flags & PR_CONNREQUIRED)) | (so->so_proto->pr_flags & PR_CONNREQUIRED)) | ||||
return (0); | return (0); | ||||
else if (kn->kn_sfflags & NOTE_LOWAT) | else if (kn->kn_sfflags & NOTE_LOWAT) | ||||
return (kn->kn_data >= kn->kn_sdata); | return (kn->kn_data >= kn->kn_sdata); | ||||
else | else | ||||
return (kn->kn_data >= so->so_snd.sb_lowat); | 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 = so->so_snd.sb_ccc; | |||||
bz: I'd suggest using sbused(&so->so_snd) there rather than directly accessing sb_ccc. | |||||
if (kn->kn_data == 0) | |||||
return (1); | |||||
else | |||||
return (0); | |||||
} | } | ||||
/*ARGSUSED*/ | /*ARGSUSED*/ | ||||
static int | static int | ||||
filt_solisten(struct knote *kn, long hint) | filt_solisten(struct knote *kn, long hint) | ||||
{ | { | ||||
struct socket *so = kn->kn_fp->f_data; | struct socket *so = kn->kn_fp->f_data; | ||||
▲ Show 20 Lines • Show All 378 Lines • Show Last 20 Lines |
I'd suggest using sbused(&so->so_snd) there rather than directly accessing sb_ccc.