/* * Handle a predicate event request. This function is only called once * when the predicate message queueing request is received. */ void netmsg_so_notify(netmsg_t msg) { struct lwkt_token *tok; struct signalsockbuf *ssb; ssb = (msg->notify.nm_etype & NM_REVENT) ? &msg->base.nm_so->so_rcv : &msg->base.nm_so->so_snd; /* * Reply immediately if the event has occured, otherwise queue the * request. * * NOTE: Socket can change if this is an accept predicate so cache * the token. */ tok = lwkt_token_pool_lookup(msg->base.nm_so); lwkt_gettoken(tok); if (msg->notify.nm_predicate(&msg->notify)) { lwkt_reltoken(tok); lwkt_replymsg(&msg->base.lmsg, msg->base.lmsg.ms_error); } else { TAILQ_INSERT_TAIL(&ssb->ssb_kq.ki_mlist, &msg->notify, nm_list); atomic_set_int(&ssb->ssb_flags, SSB_MEVENT); lwkt_reltoken(tok); } }
/* * Handle a predicate event request. This function is only called once * when the predicate message queueing request is received. */ void netmsg_so_notify(netmsg_t msg) { struct lwkt_token *tok; struct signalsockbuf *ssb; ssb = (msg->notify.nm_etype & NM_REVENT) ? &msg->base.nm_so->so_rcv : &msg->base.nm_so->so_snd; /* * Reply immediately if the event has occured, otherwise queue the * request. * * NOTE: Socket can change if this is an accept predicate so cache * the token. */ tok = lwkt_token_pool_lookup(msg->base.nm_so); lwkt_gettoken(tok); atomic_set_int(&ssb->ssb_flags, SSB_MEVENT); if (msg->notify.nm_predicate(&msg->notify)) { if (TAILQ_EMPTY(&ssb->ssb_kq.ki_mlist)) atomic_clear_int(&ssb->ssb_flags, SSB_MEVENT); lwkt_reltoken(tok); lwkt_replymsg(&msg->base.lmsg, msg->base.lmsg.ms_error); } else { TAILQ_INSERT_TAIL(&ssb->ssb_kq.ki_mlist, &msg->notify, nm_list); /* * NOTE: * If predict ever blocks, 'tok' will be released, so * SSB_MEVENT set beforehand could have been cleared * when we reach here. In case that happens, we set * SSB_MEVENT again, after the notify has been queued. */ atomic_set_int(&ssb->ssb_flags, SSB_MEVENT); lwkt_reltoken(tok); } }