Revamp the initial lwkt_abortmsg() support to normalize the abstraction. Now
[dragonfly.git] / sys / kern / uipc_socket2.c
index 47708f7..f6525a9 100644 (file)
@@ -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.7 2004/03/05 16:57:15 hsu Exp $
+ * $DragonFly: src/sys/kern/uipc_socket2.c,v 1.10 2004/04/20 01:52:22 dillon Exp $
  */
 
 #include "opt_param.h"
@@ -54,6 +54,9 @@
 #include <sys/aio.h> /* for aio_swake proto */
 #include <sys/event.h>
 
+#include <sys/thread2.h>
+#include <sys/msgport2.h>
+
 int    maxsockets;
 
 /*
@@ -195,6 +198,7 @@ sonewconn(struct socket *head, int connstatus)
        ai.p_ucred = NULL;
        ai.fd_rdir = NULL;              /* jail code cruft XXX JH */
        if (soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat, NULL) ||
+           /* Directly call function since we're already at protocol level. */
            (*so->so_proto->pr_usrreqs->pru_attach)(so, 0, &ai)) {
                sodealloc(so);
                return ((struct socket *)0);
@@ -288,16 +292,17 @@ sb_lock(sb)
 }
 
 /*
- * Wakeup processes waiting on a socket buffer.
- * Do asynchronous notification via SIGIO
- * if the socket has the SS_ASYNC flag set.
+ * Wakeup processes waiting on a socket buffer.  Do asynchronous notification
+ * via SIGIO if the socket has the SS_ASYNC flag set.
  */
 void
 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;
@@ -309,7 +314,20 @@ 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)) {
+                               TAILQ_REMOVE(&selinfo->si_mlist, msg, nm_list);
+                               lwkt_replymsg(&msg->nm_lmsg, 
+                                               msg->nm_lmsg.ms_error);
+                       }
+               }
+               if (TAILQ_EMPTY(&sb->sb_sel.si_mlist))
+                       sb->sb_flags &= ~SB_MEVENT;
+       }
 }
 
 /*