Пример #1
0
/*
 * 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);
	}
}
Пример #2
0
/*
 * 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);
	}
}