From c1d0003c51fb6564587fa970210707fadc604083 Mon Sep 17 00:00:00 2001 From: Jeffrey Hsu Date: Sat, 10 Apr 2004 00:48:06 +0000 Subject: [PATCH] Add predicate message facility. --- sys/kern/uipc_msg.c | 23 ++++++++++++++++++++++- sys/kern/uipc_socket.c | 4 +++- sys/kern/uipc_socket2.c | 26 +++++++++++++++++++++++--- sys/net/netisr.h | 20 +++++++++++++++++++- sys/sys/queue.h | 7 ++++++- sys/sys/select.h | 10 ++++++---- sys/sys/socketvar.h | 8 +++++--- 7 files changed, 84 insertions(+), 14 deletions(-) diff --git a/sys/kern/uipc_msg.c b/sys/kern/uipc_msg.c index b32e2ff265..0c404b56b9 100644 --- a/sys/kern/uipc_msg.c +++ b/sys/kern/uipc_msg.c @@ -27,7 +27,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $DragonFly: src/sys/kern/uipc_msg.c,v 1.7 2004/04/10 00:10:42 hsu Exp $ + * $DragonFly: src/sys/kern/uipc_msg.c,v 1.8 2004/04/10 00:48:06 hsu Exp $ */ #include @@ -641,3 +641,24 @@ netmsg_pr_dispatcher(struct netmsg *msg) } lwkt_replymsg(&msg->nm_lmsg, error); } + +void +msg_notify_handler(struct netmsg *msg0) +{ + struct netmsg_so_notify *msg = (struct netmsg_so_notify *)msg0; + struct sockbuf *sb; + + /* Check if event occurred. */ + if (msg->nm_predicate(msg0)) { + lwkt_replymsg(&msg->nm_lmsg, msg->nm_lmsg.ms_error); + return; + } + + /* If not, queue the predicate check. */ + sb = (msg->nm_etype & NM_REVENT) ? + &msg->nm_so->so_rcv : + &msg->nm_so->so_snd; + + TAILQ_INSERT_TAIL(&sb->sb_sel.si_mlist, msg, nm_list); + sb->sb_flags |= SB_MEVENT; +} diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 44cca05cd6..86d6a4356b 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -33,7 +33,7 @@ * * @(#)uipc_socket.c 8.3 (Berkeley) 4/15/94 * $FreeBSD: src/sys/kern/uipc_socket.c,v 1.68.2.24 2003/11/11 17:18:18 silby Exp $ - * $DragonFly: src/sys/kern/uipc_socket.c,v 1.16 2004/03/27 11:48:48 hsu Exp $ + * $DragonFly: src/sys/kern/uipc_socket.c,v 1.17 2004/04/10 00:48:06 hsu Exp $ */ #include "opt_inet.h" @@ -119,6 +119,8 @@ soalloc(waitok) bzero(so, sizeof *so); so->so_gencnt = ++so_gencnt; TAILQ_INIT(&so->so_aiojobq); + TAILQ_INIT(&so->so_rcv.sb_sel.si_mlist); + TAILQ_INIT(&so->so_snd.sb_sel.si_mlist); } return so; } diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c index 5899544092..ce5a733c26 100644 --- a/sys/kern/uipc_socket2.c +++ b/sys/kern/uipc_socket2.c @@ -32,7 +32,7 @@ * * @(#)uipc_socket2.c 8.1 (Berkeley) 6/10/93 * $FreeBSD: src/sys/kern/uipc_socket2.c,v 1.55.2.17 2002/08/31 19:04:55 dwmalone Exp $ - * $DragonFly: src/sys/kern/uipc_socket2.c,v 1.8 2004/03/06 01:58:54 hsu Exp $ + * $DragonFly: src/sys/kern/uipc_socket2.c,v 1.9 2004/04/10 00:48:06 hsu Exp $ */ #include "opt_param.h" @@ -54,6 +54,9 @@ #include /* for aio_swake proto */ #include +#include +#include + int maxsockets; /* @@ -298,7 +301,9 @@ sowakeup(so, sb) struct socket *so; struct sockbuf *sb; { - selwakeup(&sb->sb_sel); + struct selinfo *selinfo = &sb->sb_sel; + + selwakeup(selinfo); sb->sb_flags &= ~SB_SEL; if (sb->sb_flags & SB_WAIT) { sb->sb_flags &= ~SB_WAIT; @@ -310,7 +315,22 @@ sowakeup(so, sb) (*so->so_upcall)(so, so->so_upcallarg, M_DONTWAIT); if (sb->sb_flags & SB_AIO) aio_swake(so, sb); - KNOTE(&sb->sb_sel.si_note, 0); + KNOTE(&selinfo->si_note, 0); + if (sb->sb_flags & SB_MEVENT) { + struct netmsg_so_notify *msg, *nmsg; + + TAILQ_FOREACH_MUTABLE(msg, &selinfo->si_mlist, nm_list, nmsg) { + if (msg->nm_predicate((struct netmsg *)msg)) { + struct lwkt_msg *lmsg = &msg->nm_lmsg; + + lwkt_replymsg(lmsg, lmsg->ms_error); + TAILQ_REMOVE(&selinfo->si_mlist, msg, nm_list); + } + } + + if (TAILQ_EMPTY(&sb->sb_sel.si_mlist)) + sb->sb_flags &= ~SB_MEVENT; + } } /* diff --git a/sys/net/netisr.h b/sys/net/netisr.h index 819e1cf2bc..7069a44e06 100644 --- a/sys/net/netisr.h +++ b/sys/net/netisr.h @@ -32,7 +32,7 @@ * * @(#)netisr.h 8.1 (Berkeley) 6/10/93 * $FreeBSD: src/sys/net/netisr.h,v 1.21.2.5 2002/02/09 23:02:39 luigi Exp $ - * $DragonFly: src/sys/net/netisr.h,v 1.12 2004/04/09 22:34:09 hsu Exp $ + * $DragonFly: src/sys/net/netisr.h,v 1.13 2004/04/10 00:48:06 hsu Exp $ */ #ifndef _NET_NETISR_H_ @@ -80,6 +80,7 @@ struct netmsg; typedef void (*netisr_fn_t)(struct netmsg *); +typedef boolean_t (*msg_predicate_fn_t)(struct netmsg *); /* * Base class. All net messages must start with the same fields. @@ -109,6 +110,20 @@ struct netmsg_pr_timeout { void (*nm_prfn) (void); }; +TAILQ_HEAD(notifymsglist, netmsg_so_notify); + +struct netmsg_so_notify { + struct lwkt_msg nm_lmsg; + netisr_fn_t nm_handler; + msg_predicate_fn_t nm_predicate; + struct socket *nm_so; + int nm_etype; /* receive or send event */ + TAILQ_ENTRY(netmsg_so_notify) nm_list; +}; + +#define NM_REVENT 0x1 /* event on receive buffer */ +#define NM_SEVENT 0x2 /* event on send buffer */ + /* * for dispatching pr_ functions, * until they can be converted to message-passing @@ -143,6 +158,9 @@ void netmsg_pr_dispatcher(struct netmsg *); #define CMD_NETMSG_PR_TIMEOUT (MSG_CMD_NETMSG | 0x0018) #define CMD_NETMSG_ONCPU (MSG_CMD_NETMSG | 0x0019) +#define CMD_NETMSG_NOTIFY (MSG_CMD_NETMSG | 0x0020) + +void msg_notify_handler(struct netmsg *); typedef lwkt_port_t (*lwkt_portfn_t)(struct mbuf *); diff --git a/sys/sys/queue.h b/sys/sys/queue.h index ec1fe8bf87..0d4054155e 100644 --- a/sys/sys/queue.h +++ b/sys/sys/queue.h @@ -32,7 +32,7 @@ * * @(#)queue.h 8.5 (Berkeley) 8/20/94 * $FreeBSD: src/sys/sys/queue.h,v 1.32.2.7 2002/04/17 14:21:02 des Exp $ - * $DragonFly: src/sys/sys/queue.h,v 1.4 2003/11/09 02:22:37 dillon Exp $ + * $DragonFly: src/sys/sys/queue.h,v 1.5 2004/04/10 00:48:06 hsu Exp $ */ #ifndef _SYS_QUEUE_H_ @@ -359,6 +359,11 @@ struct { \ (var); \ (var) = TAILQ_PREV((var), headname, field)) +#define TAILQ_FOREACH_MUTABLE(var, head, field, nvar) \ + for ((var) = TAILQ_FIRST((head)); \ + (var) && ((nvar) = TAILQ_NEXT((var), field), (var)); \ + (var) = (nvar)) + #define TAILQ_INIT(head) do { \ TAILQ_FIRST((head)) = NULL; \ (head)->tqh_last = &TAILQ_FIRST((head)); \ diff --git a/sys/sys/select.h b/sys/sys/select.h index 5490af9491..da3ed1f02a 100644 --- a/sys/sys/select.h +++ b/sys/sys/select.h @@ -32,22 +32,24 @@ * * @(#)select.h 8.2 (Berkeley) 1/4/94 * $FreeBSD: src/sys/sys/select.h,v 1.6.2.1 2000/05/05 03:50:02 jlemon Exp $ - * $DragonFly: src/sys/sys/select.h,v 1.4 2003/08/20 07:31:21 rob Exp $ + * $DragonFly: src/sys/sys/select.h,v 1.5 2004/04/10 00:48:06 hsu Exp $ */ #ifndef _SYS_SELECT_H_ #define _SYS_SELECT_H_ #include /* for struct klist */ +#include /* for struct notifymsglist */ /* * Used to maintain information about processes that wish to be * notified when I/O becomes possible. */ struct selinfo { - pid_t si_pid; /* process to be notified */ - struct klist si_note; /* kernel note list */ - short si_flags; /* see below */ + pid_t si_pid; /* process to be notified */ + struct klist si_note; /* kernel note list */ + struct notifymsglist si_mlist; /* list of pending predicate messages */ + short si_flags; /* see below */ }; #define SI_COLL 0x0001 /* collision occurred */ diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h index 184dc177aa..6dd53ec2c0 100644 --- a/sys/sys/socketvar.h +++ b/sys/sys/socketvar.h @@ -32,7 +32,7 @@ * * @(#)socketvar.h 8.3 (Berkeley) 2/19/95 * $FreeBSD: src/sys/sys/socketvar.h,v 1.46.2.10 2003/08/24 08:24:39 hsu Exp $ - * $DragonFly: src/sys/sys/socketvar.h,v 1.11 2004/03/27 11:48:48 hsu Exp $ + * $DragonFly: src/sys/sys/socketvar.h,v 1.12 2004/04/10 00:48:06 hsu Exp $ */ #ifndef _SYS_SOCKETVAR_H_ @@ -107,6 +107,7 @@ struct socket { #define SB_NOINTR 0x40 /* operations not interruptible */ #define SB_AIO 0x80 /* AIO operations queued */ #define SB_KNOTE 0x100 /* kernel note attached */ +#define SB_MEVENT 0x200 /* need message event notification */ void (*so_upcall) (struct socket *, void *, int); void *so_upcallarg; @@ -179,8 +180,9 @@ struct xsocket { /* * Do we need to notify the other side when I/O is possible? */ -#define sb_notify(sb) (((sb)->sb_flags & (SB_WAIT | SB_SEL | SB_ASYNC | \ - SB_UPCALL | SB_AIO | SB_KNOTE)) != 0) +#define sb_notify(sb) \ +(((sb)->sb_flags & \ + (SB_WAIT | SB_SEL | SB_ASYNC | SB_UPCALL | SB_AIO | SB_KNOTE | SB_MEVENT))) /* * How much space is there in a socket buffer (so->so_snd or so->so_rcv)? -- 2.41.0