- KERNEL_DEBUG(DBG_MISC_POST|DBG_FUNC_END, 0,0,0,1,0);
-}
-
-#if SOCKETS
-/*
- * given either a sockbuf or a socket run down the
- * event list and queue ready events found...
- * the socket must be locked by the caller
- */
-void
-postevent(struct socket *sp, struct sockbuf *sb, int event)
-{
- int mask;
- struct eventqelt *evq;
- struct tcpcb *tp;
-
- if (sb)
- sp = sb->sb_so;
- if (sp == NULL)
- return;
-
- KERNEL_DEBUG(DBG_MISC_POST|DBG_FUNC_START, (int)sp, event, 0, 0, 0);
-
- for (evq = sp->so_evlist.tqh_first;
- evq != NULL; evq = evq->ee_slist.tqe_next) {
-
- if (evq->ee_eventmask == 0)
- continue;
- mask = 0;
-
- /* ready for reading:
- - byte cnt >= receive low water mark
- - read-half of conn closed
- - conn pending for listening sock
- - socket error pending
-
- ready for writing
- - byte cnt avail >= send low water mark
- - write half of conn closed
- - socket error pending
- - non-blocking conn completed successfully
-
- exception pending
- - out of band data
- - sock at out of band mark
- */
-
- switch (event & EV_DMASK) {
-
- case EV_OOB:
- if ((evq->ee_eventmask & EV_EX)) {
- if (sp->so_oobmark || ((sp->so_state & SS_RCVATMARK)))
- mask |= EV_EX|EV_OOB;
- }
- break;
-
- case EV_RWBYTES|EV_OOB:
- if ((evq->ee_eventmask & EV_EX)) {
- if (sp->so_oobmark || ((sp->so_state & SS_RCVATMARK)))
- mask |= EV_EX|EV_OOB;
- }
- /*
- * fall into the next case
- */
- case EV_RWBYTES:
- if ((evq->ee_eventmask & EV_RE) && soreadable(sp)) {
- /* for AFP/OT purposes; may go away in future */
- if ((SOCK_DOM(sp) == PF_INET ||
- SOCK_DOM(sp) == PF_INET6) &&
- SOCK_PROTO(sp) == IPPROTO_TCP &&
- (sp->so_error == ECONNREFUSED ||
- sp->so_error == ECONNRESET)) {
- if (sp->so_pcb == NULL ||
- sotoinpcb(sp)->inp_state ==
- INPCB_STATE_DEAD ||
- (tp = sototcpcb(sp)) == NULL ||
- tp->t_state == TCPS_CLOSED) {
- mask |= EV_RE|EV_RESET;
- break;
- }
- }
- mask |= EV_RE;
- evq->ee_req.er_rcnt = sp->so_rcv.sb_cc;
-
- if (sp->so_state & SS_CANTRCVMORE) {
- mask |= EV_FIN;
- break;
- }
- }
- if ((evq->ee_eventmask & EV_WR) && sowriteable(sp)) {
- /* for AFP/OT purposes; may go away in future */
- if ((SOCK_DOM(sp) == PF_INET ||
- SOCK_DOM(sp) == PF_INET6) &&
- SOCK_PROTO(sp) == IPPROTO_TCP &&
- (sp->so_error == ECONNREFUSED ||
- sp->so_error == ECONNRESET)) {
- if (sp->so_pcb == NULL ||
- sotoinpcb(sp)->inp_state ==
- INPCB_STATE_DEAD ||
- (tp = sototcpcb(sp)) == NULL ||
- tp->t_state == TCPS_CLOSED) {
- mask |= EV_WR|EV_RESET;
- break;
- }
- }
- mask |= EV_WR;
- evq->ee_req.er_wcnt = sbspace(&sp->so_snd);
- }
- break;
-
- case EV_RCONN:
- if ((evq->ee_eventmask & EV_RE)) {
- mask |= EV_RE|EV_RCONN;
- evq->ee_req.er_rcnt = sp->so_qlen + 1; // incl this one
- }
- break;
-
- case EV_WCONN:
- if ((evq->ee_eventmask & EV_WR)) {
- mask |= EV_WR|EV_WCONN;
- }
- break;
-
- case EV_RCLOSED:
- if ((evq->ee_eventmask & EV_RE)) {
- mask |= EV_RE|EV_RCLOSED;
- }
- break;
-
- case EV_WCLOSED:
- if ((evq->ee_eventmask & EV_WR)) {
- mask |= EV_WR|EV_WCLOSED;
- }
- break;
-
- case EV_FIN:
- if (evq->ee_eventmask & EV_RE) {
- mask |= EV_RE|EV_FIN;
- }
- break;
-
- case EV_RESET:
- case EV_TIMEOUT:
- if (evq->ee_eventmask & EV_RE) {
- mask |= EV_RE | event;
- }
- if (evq->ee_eventmask & EV_WR) {
- mask |= EV_WR | event;
- }
- break;
-
- default:
- KERNEL_DEBUG(DBG_MISC_POST|DBG_FUNC_END, (int)sp, -1, 0, 0, 0);
- return;
- } /* switch */
-
- KERNEL_DEBUG(DBG_MISC_POST, (int)evq, evq->ee_eventmask, evq->ee_req.er_eventbits, mask, 0);
-
- if (mask) {
- /*
- * disarm... postevents are nops until this event is 'read' via
- * waitevent and then re-armed via modwatch
- */
- evq->ee_eventmask = 0;