diff options
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_event.c | 1 | ||||
-rw-r--r-- | sys/kern/sys_generic.c | 17 | ||||
-rw-r--r-- | sys/kern/sys_pipe.c | 1 | ||||
-rw-r--r-- | sys/kern/tty.c | 2 | ||||
-rw-r--r-- | sys/kern/tty_pts.c | 2 | ||||
-rw-r--r-- | sys/kern/uipc_mqueue.c | 2 | ||||
-rw-r--r-- | sys/kern/uipc_socket.c | 2 | ||||
-rw-r--r-- | sys/kern/vfs_subr.c | 1 |
8 files changed, 28 insertions, 0 deletions
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index c512b0ac734c..dc11411fd5df 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -1704,6 +1704,7 @@ kqueue_close(struct file *fp, struct thread *td) SLIST_REMOVE(&fdp->fd_kqlist, kq, kqueue, kq_list); FILEDESC_XUNLOCK(fdp); + seldrain(&kq->kq_sel); knlist_destroy(&kq->kq_sel.si_note); mtx_destroy(&kq->kq_lock); kq->kq_fdp = NULL; diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c index 6edd4fbdeeee..7b45efa2ff51 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -1490,6 +1490,23 @@ selfdfree(struct seltd *stp, struct selfd *sfp) uma_zfree(selfd_zone, sfp); } +/* Drain the waiters tied to all the selfd belonging the specified selinfo. */ +void +seldrain(sip) + struct selinfo *sip; +{ + + /* + * This feature is already provided by doselwakeup(), thus it is + * enough to go for it. + * Eventually, the context, should take care to avoid races + * between thread calling select()/poll() and file descriptor + * detaching, but, again, the races are just the same as + * selwakeup(). + */ + doselwakeup(sip, -1); +} + /* * Record a select request. */ diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c index 14e12075f1d0..c44a2c964e49 100644 --- a/sys/kern/sys_pipe.c +++ b/sys/kern/sys_pipe.c @@ -1517,6 +1517,7 @@ pipeclose(cpipe) */ knlist_clear(&cpipe->pipe_sel.si_note, 1); cpipe->pipe_present = PIPE_FINALIZED; + seldrain(&cpipe->pipe_sel); knlist_destroy(&cpipe->pipe_sel.si_note); /* diff --git a/sys/kern/tty.c b/sys/kern/tty.c index 77c02dd57dd7..ce49f972b2fc 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -1022,6 +1022,8 @@ tty_dealloc(void *arg) MPASS(ttyinq_getsize(&tp->t_inq) == 0); MPASS(ttyoutq_getsize(&tp->t_outq) == 0); + seldrain(&tp->t_inpoll); + seldrain(&tp->t_outpoll); knlist_destroy(&tp->t_inpoll.si_note); knlist_destroy(&tp->t_outpoll.si_note); diff --git a/sys/kern/tty_pts.c b/sys/kern/tty_pts.c index cf9f94d375d4..f2f5c4e71bd8 100644 --- a/sys/kern/tty_pts.c +++ b/sys/kern/tty_pts.c @@ -688,6 +688,8 @@ ptsdrv_free(void *softc) racct_sub_cred(psc->pts_cred, RACCT_NPTS, 1); crfree(psc->pts_cred); + seldrain(&psc->pts_inpoll); + seldrain(&psc->pts_outpoll); knlist_destroy(&psc->pts_inpoll.si_note); knlist_destroy(&psc->pts_outpoll.si_note); diff --git a/sys/kern/uipc_mqueue.c b/sys/kern/uipc_mqueue.c index fbd78c16a288..b91b890e8a27 100644 --- a/sys/kern/uipc_mqueue.c +++ b/sys/kern/uipc_mqueue.c @@ -1562,6 +1562,8 @@ mqueue_free(struct mqueue *mq) } mtx_destroy(&mq->mq_mutex); + seldrain(&mq->mq_rsel); + seldrain(&mq->mq_wsel); knlist_destroy(&mq->mq_rsel.si_note); knlist_destroy(&mq->mq_wsel.si_note); uma_zfree(mqueue_zone, mq); diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 990c6bad11f8..bbd4fad38749 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -661,6 +661,8 @@ sofree(struct socket *so) */ sbdestroy(&so->so_snd, so); sbdestroy(&so->so_rcv, so); + seldrain(&so->so_snd.sb_sel); + seldrain(&so->so_rcv.sb_sel); knlist_destroy(&so->so_rcv.sb_sel.si_note); knlist_destroy(&so->so_snd.sb_sel.si_note); sodealloc(so); diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index a9fe8d10773d..325ca99deb32 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -3312,6 +3312,7 @@ vbusy(struct vnode *vp) static void destroy_vpollinfo(struct vpollinfo *vi) { + seldrain(&vi->vpi_selinfo); knlist_destroy(&vi->vpi_selinfo.si_note); mtx_destroy(&vi->vpi_lock); uma_zfree(vnodepoll_zone, vi); |