-
- KERNEL_DEBUG(DBG_MISC_DEQUEUE|DBG_FUNC_START,p,eqp,0,0,0);
-
- if (eqp && ((eqp->ee_flags & EV_QUEUED) == NULL)) {
- KERNEL_DEBUG(DBG_MISC_DEQUEUE|DBG_FUNC_END,0,0,0,0,0);
- return(NULL);
- }
- if (p->p_evlist.tqh_first == NULL) {
- KERNEL_DEBUG(DBG_MISC_DEQUEUE|DBG_FUNC_END,0,0,0,0,0);
- return(NULL);
- }
- if (eqp == NULL) { // remove first
- eqp = p->p_evlist.tqh_first;
- }
- TAILQ_REMOVE(&p->p_evlist, eqp, ee_plist);
- eqp->ee_flags &= ~EV_QUEUED;
- KERNEL_DEBUG(DBG_MISC_DEQUEUE|DBG_FUNC_END,eqp,0,0,0,0);
- return(eqp);
+ 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)) {
+ if (sp->so_error) {
+ if ((sp->so_type == SOCK_STREAM) && ((sp->so_error == ECONNREFUSED) || (sp->so_error == ECONNRESET))) {
+ if ((sp->so_pcb == 0) || (((struct inpcb *)sp->so_pcb)->inp_state == INPCB_STATE_DEAD) || !(tp = sototcpcb(sp)) ||
+ (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)) {
+ if (sp->so_error) {
+ if ((sp->so_type == SOCK_STREAM) && ((sp->so_error == ECONNREFUSED) || (sp->so_error == ECONNRESET))) {
+ if ((sp->so_pcb == 0) || (((struct inpcb *)sp->so_pcb)->inp_state == INPCB_STATE_DEAD) || !(tp = sototcpcb(sp)) ||
+ (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;
+
+ /*
+ * since events are disarmed until after the waitevent
+ * the ee_req.er_xxxx fields can't change once we've
+ * inserted this event into the proc queue...
+ * since waitevent can't see this event until we
+ * enqueue it, waitevent will see a 'consistent'
+ * snapshot of the event, even though it won't hold
+ * the socket lock, and we're updating the event outside
+ * of the proc lock, which it will hold
+ */
+ evq->ee_req.er_eventbits |= mask;
+
+ evprocenque(evq);
+ }
+ }
+ KERNEL_DEBUG(DBG_MISC_POST|DBG_FUNC_END, (int)sp, 0, 0, 0, 0);