sodealloc(struct socket *so)
{
KKASSERT((so->so_state & (SS_INCOMP | SS_COMP)) == 0);
+ /* TODO: assert accept queues are empty, after unix socket is fixed */
+
if (so->so_rcv.ssb_hiwat)
(void)chgsbsize(so->so_cred->cr_uidinfo,
&so->so_rcv.ssb_hiwat, 0, RLIM_INFINITY);
return so_pru_listen(so, td);
}
+static void
+soqflush(struct socket *so)
+{
+ lwkt_getpooltoken(so);
+ if (so->so_options & SO_ACCEPTCONN) {
+ struct socket *sp;
+
+ while ((sp = TAILQ_FIRST(&so->so_incomp)) != NULL) {
+ KKASSERT((sp->so_state & (SS_INCOMP | SS_COMP)) ==
+ SS_INCOMP);
+ TAILQ_REMOVE(&so->so_incomp, sp, so_list);
+ so->so_incqlen--;
+ soclrstate(sp, SS_INCOMP);
+ soabort_async(sp, TRUE);
+ }
+ while ((sp = TAILQ_FIRST(&so->so_comp)) != NULL) {
+ KKASSERT((sp->so_state & (SS_INCOMP | SS_COMP)) ==
+ SS_COMP);
+ TAILQ_REMOVE(&so->so_comp, sp, so_list);
+ so->so_qlen--;
+ soclrstate(sp, SS_COMP);
+ soabort_async(sp, TRUE);
+ }
+ }
+ lwkt_relpooltoken(so);
+}
+
/*
* Destroy a disconnected socket. This routine is a NOP if entities
* still have a reference on the socket:
KKASSERT(so->so_pcb == NULL && (so->so_state & SS_NOFDREF));
KKASSERT((so->so_state & SS_ASSERTINPROG) == 0);
- /*
- * We're done, remove ourselves from the accept queue we are
- * on, if we are on one.
- */
if (head != NULL) {
+ /*
+ * We're done, remove ourselves from the accept queue we are
+ * on, if we are on one.
+ */
if (so->so_state & SS_INCOMP) {
KKASSERT((so->so_state & (SS_INCOMP | SS_COMP)) ==
SS_INCOMP);
soclrstate(so, SS_INCOMP);
so->so_head = NULL;
lwkt_relpooltoken(head);
+ } else {
+ /* Flush accept queues, if we are accepting. */
+ soqflush(so);
}
ssb_release(&so->so_snd, so);
sorflush(so);
void
sodiscard(struct socket *so)
{
- lwkt_getpooltoken(so);
- if (so->so_options & SO_ACCEPTCONN) {
- struct socket *sp;
-
- while ((sp = TAILQ_FIRST(&so->so_incomp)) != NULL) {
- KKASSERT((sp->so_state & (SS_INCOMP | SS_COMP)) ==
- SS_INCOMP);
- TAILQ_REMOVE(&so->so_incomp, sp, so_list);
- so->so_incqlen--;
- soclrstate(sp, SS_INCOMP);
- soabort_async(sp, TRUE);
- }
- while ((sp = TAILQ_FIRST(&so->so_comp)) != NULL) {
- KKASSERT((sp->so_state & (SS_INCOMP | SS_COMP)) ==
- SS_COMP);
- TAILQ_REMOVE(&so->so_comp, sp, so_list);
- so->so_qlen--;
- soclrstate(sp, SS_COMP);
- soabort_async(sp, TRUE);
- }
- }
- lwkt_relpooltoken(so);
-
if (so->so_state & SS_NOFDREF)
panic("soclose: NOFDREF");
sosetstate(so, SS_NOFDREF); /* take ref */