Add a vclean_unlocked() call that allows HAMMER to try to get rid of a
[dragonfly.git] / sys / kern / uipc_msg.c
blob0c412f9b47ccec0b56bfd1e35d1804b3ce9f114d
1 /*
2 * Copyright (c) 2003, 2004 Jeffrey M. Hsu. All rights reserved.
3 * Copyright (c) 2003, 2004 The DragonFly Project. All rights reserved.
4 *
5 * This code is derived from software contributed to The DragonFly Project
6 * by Jeffrey M. Hsu.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of The DragonFly Project nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific, prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
30 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
33 * $DragonFly: src/sys/kern/uipc_msg.c,v 1.23 2008/07/10 00:19:27 aggelos Exp $
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/kernel.h>
39 #include <sys/msgport.h>
40 #include <sys/protosw.h>
41 #include <sys/socket.h>
42 #include <sys/socketvar.h>
43 #include <sys/socketops.h>
44 #include <sys/thread.h>
45 #include <sys/thread2.h>
46 #include <sys/msgport2.h>
47 #include <vm/pmap.h>
48 #include <net/netmsg2.h>
50 #include <net/netisr.h>
51 #include <net/netmsg.h>
53 int
54 so_pru_abort(struct socket *so)
56 int error;
57 struct netmsg_pru_abort msg;
58 lwkt_port_t port;
60 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_ABORT);
61 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
62 netmsg_pru_abort);
63 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_abort;
64 msg.nm_so = so;
65 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
66 return (error);
69 int
70 so_pru_accept(struct socket *so, struct sockaddr **nam)
72 /* Block (memory allocation) in process context. XXX JH */
73 return ((*so->so_proto->pr_usrreqs->pru_accept)(so, nam));
75 #ifdef notdef
76 int error;
77 struct netmsg_pru_accept msg;
78 lwkt_port_t port;
80 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_ACCEPT);
81 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
82 netmsg_pru_accept);
83 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_accept;
84 msg.nm_so = so;
85 msg.nm_nam = nam;
86 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
87 return (error);
88 #endif
91 int
92 so_pru_attach(struct socket *so, int proto, struct pru_attach_info *ai)
94 int error;
95 struct netmsg_pru_attach msg;
96 lwkt_port_t port;
98 port = so->so_proto->pr_mport(NULL, NULL, NULL, PRU_ATTACH);
99 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
100 netmsg_pru_attach);
101 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_attach;
102 msg.nm_so = so;
103 msg.nm_proto = proto;
104 msg.nm_ai = ai;
105 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
106 return (error);
110 so_pru_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
112 int error;
113 struct netmsg_pru_bind msg;
114 lwkt_port_t port;
116 /* Send mesg to thread for new address. */
117 port = so->so_proto->pr_mport(NULL, nam, NULL, PRU_BIND);
118 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
119 netmsg_pru_bind);
120 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_bind;
121 msg.nm_so = so;
122 msg.nm_nam = nam;
123 msg.nm_td = td; /* used only for prison_ip() XXX JH */
124 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
125 return (error);
129 so_pru_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
131 int error;
132 struct netmsg_pru_connect msg;
133 lwkt_port_t port;
135 port = so->so_proto->pr_mport(so, nam, NULL, PRU_CONNECT);
136 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
137 netmsg_pru_connect);
138 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_connect;
139 msg.nm_so = so;
140 msg.nm_nam = nam;
141 msg.nm_td = td;
142 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
143 return (error);
147 so_pru_connect2(struct socket *so1, struct socket *so2)
149 int error;
150 struct netmsg_pru_connect2 msg;
151 lwkt_port_t port;
153 port = so1->so_proto->pr_mport(so1, NULL, NULL, PRU_CONNECT2);
154 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
155 netmsg_pru_connect2);
156 msg.nm_prufn = so1->so_proto->pr_usrreqs->pru_connect2;
157 msg.nm_so1 = so1;
158 msg.nm_so2 = so2;
159 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
160 return (error);
164 so_pru_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp)
166 return ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, data, ifp,
167 curthread));
168 #ifdef gag /* does copyin and copyout deep inside stack XXX JH */
169 int error;
170 struct netmsg_pru_control msg;
171 lwkt_port_t port;
173 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_CONTROL);
174 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
175 netmsg_pru_control);
176 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_control;
177 msg.nm_so = so;
178 msg.nm_cmd = cmd;
179 msg.nm_data = data;
180 msg.nm_ifp = ifp;
181 msg.nm_td = td;
182 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
183 return (error);
184 #endif
188 so_pru_detach(struct socket *so)
190 int error;
191 struct netmsg_pru_detach msg;
192 lwkt_port_t port;
194 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_DETACH);
195 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
196 netmsg_pru_detach);
197 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_detach;
198 msg.nm_so = so;
199 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
200 return (error);
204 so_pru_disconnect(struct socket *so)
206 int error;
207 struct netmsg_pru_disconnect msg;
208 lwkt_port_t port;
210 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_DISCONNECT);
211 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
212 netmsg_pru_disconnect);
213 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_disconnect;
214 msg.nm_so = so;
215 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
216 return (error);
220 so_pru_listen(struct socket *so, struct thread *td)
222 int error;
223 struct netmsg_pru_listen msg;
224 lwkt_port_t port;
226 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_LISTEN);
227 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
228 netmsg_pru_listen);
229 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_listen;
230 msg.nm_so = so;
231 msg.nm_td = td; /* used only for prison_ip() XXX JH */
232 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
233 return (error);
237 so_pru_peeraddr(struct socket *so, struct sockaddr **nam)
239 int error;
240 struct netmsg_pru_peeraddr msg;
241 lwkt_port_t port;
243 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_PEERADDR);
244 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
245 netmsg_pru_peeraddr);
246 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_peeraddr;
247 msg.nm_so = so;
248 msg.nm_nam = nam;
249 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
250 return (error);
254 so_pru_rcvd(struct socket *so, int flags)
256 int error;
257 struct netmsg_pru_rcvd msg;
258 lwkt_port_t port;
260 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_RCVD);
261 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
262 netmsg_pru_rcvd);
263 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_rcvd;
264 msg.nm_so = so;
265 msg.nm_flags = flags;
266 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
267 return (error);
271 so_pru_rcvoob(struct socket *so, struct mbuf *m, int flags)
273 int error;
274 struct netmsg_pru_rcvoob msg;
275 lwkt_port_t port;
277 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_RCVOOB);
278 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
279 netmsg_pru_rcvoob);
280 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_rcvoob;
281 msg.nm_so = so;
282 msg.nm_m = m;
283 msg.nm_flags = flags;
284 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
285 return (error);
289 so_pru_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
290 struct mbuf *control, struct thread *td)
292 int error;
293 struct netmsg_pru_send msg;
294 lwkt_port_t port;
296 port = so->so_proto->pr_mport(so, addr, &m, PRU_SEND);
297 if (port == NULL) {
298 KKASSERT(m == NULL);
299 return EINVAL;
302 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
303 netmsg_pru_send);
304 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_send;
305 msg.nm_so = so;
306 msg.nm_flags = flags;
307 msg.nm_m = m;
308 msg.nm_addr = addr;
309 msg.nm_control = control;
310 msg.nm_td = td;
311 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
312 return (error);
316 so_pru_sense(struct socket *so, struct stat *sb)
318 int error;
319 struct netmsg_pru_sense msg;
320 lwkt_port_t port;
322 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_SENSE);
323 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
324 netmsg_pru_sense);
325 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sense;
326 msg.nm_so = so;
327 msg.nm_stat = sb;
328 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
329 return (error);
333 so_pru_shutdown(struct socket *so)
335 int error;
336 struct netmsg_pru_shutdown msg;
337 lwkt_port_t port;
339 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_SHUTDOWN);
340 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
341 netmsg_pru_shutdown);
342 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_shutdown;
343 msg.nm_so = so;
344 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
345 return (error);
349 so_pru_sockaddr(struct socket *so, struct sockaddr **nam)
351 int error;
352 struct netmsg_pru_sockaddr msg;
353 lwkt_port_t port;
355 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_SOCKADDR);
356 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
357 netmsg_pru_sockaddr);
358 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sockaddr;
359 msg.nm_so = so;
360 msg.nm_nam = nam;
361 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
362 return (error);
366 so_pru_sopoll(struct socket *so, int events, struct ucred *cred)
368 int error;
369 struct netmsg_pru_sopoll msg;
370 lwkt_port_t port;
372 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_SOPOLL);
373 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
374 netmsg_pru_sopoll);
375 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sopoll;
376 msg.nm_so = so;
377 msg.nm_events = events;
378 msg.nm_cred = cred;
379 msg.nm_td = curthread;
380 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
381 return (error);
385 so_pru_ctloutput(struct socket *so, struct sockopt *sopt)
387 struct netmsg_pru_ctloutput msg;
388 lwkt_port_t port;
389 int error;
391 KKASSERT(!sopt->sopt_val || kva_p(sopt->sopt_val));
392 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_CTLOUTPUT);
393 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
394 netmsg_pru_ctloutput);
395 /* TBD: move pr_ctloutput to pr_usrreqs */
396 msg.nm_prufn = so->so_proto->pr_ctloutput;
397 msg.nm_so = so;
398 msg.nm_sopt = sopt;
399 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
400 return (error);
404 * If we convert all the protosw pr_ functions for all the protocols
405 * to take a message directly, this layer can go away. For the moment
406 * our dispatcher ignores the return value, but since we are handling
407 * the replymsg ourselves we return EASYNC by convention.
409 void
410 netmsg_pru_abort(netmsg_t msg)
412 struct netmsg_pru_abort *nm = (void *)msg;
414 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so));
417 #ifdef notused
418 void
419 netmsg_pru_accept(netmsg_t msg)
421 struct netmsg_pru_accept *nm = (void *)msg;
423 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_nam));
425 #endif
427 void
428 netmsg_pru_attach(netmsg_t msg)
430 struct netmsg_pru_attach *nm = (void *)msg;
432 lwkt_replymsg(&msg->nm_lmsg,
433 nm->nm_prufn(nm->nm_so, nm->nm_proto, nm->nm_ai));
436 void
437 netmsg_pru_bind(netmsg_t msg)
439 struct netmsg_pru_bind *nm = (void *)msg;
441 lwkt_replymsg(&msg->nm_lmsg,
442 nm->nm_prufn(nm->nm_so, nm->nm_nam, nm->nm_td));
445 void
446 netmsg_pru_connect(netmsg_t msg)
448 struct netmsg_pru_connect *nm = (void *)msg;
450 lwkt_replymsg(&msg->nm_lmsg,
451 nm->nm_prufn(nm->nm_so, nm->nm_nam, nm->nm_td));
454 void
455 netmsg_pru_connect2(netmsg_t msg)
457 struct netmsg_pru_connect2 *nm = (void *)msg;
459 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so1, nm->nm_so2));
462 void
463 netmsg_pru_control(netmsg_t msg)
465 struct netmsg_pru_control *nm = (void *)msg;
466 int error;
468 error = nm->nm_prufn(nm->nm_so, nm->nm_cmd, nm->nm_data,
469 nm->nm_ifp, nm->nm_td);
470 lwkt_replymsg(&msg->nm_lmsg, error);
473 void
474 netmsg_pru_detach(netmsg_t msg)
476 struct netmsg_pru_detach *nm = (void *)msg;
478 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so));
481 void
482 netmsg_pru_disconnect(netmsg_t msg)
484 struct netmsg_pru_disconnect *nm = (void *)msg;
486 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so));
489 void
490 netmsg_pru_listen(netmsg_t msg)
492 struct netmsg_pru_listen *nm = (void *)msg;
494 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_td));
497 void
498 netmsg_pru_peeraddr(netmsg_t msg)
500 struct netmsg_pru_peeraddr *nm = (void *)msg;
502 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_nam));
505 void
506 netmsg_pru_rcvd(netmsg_t msg)
508 struct netmsg_pru_rcvd *nm = (void *)msg;
510 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_flags));
513 void
514 netmsg_pru_rcvoob(netmsg_t msg)
516 struct netmsg_pru_rcvoob *nm = (void *)msg;
518 lwkt_replymsg(&msg->nm_lmsg,
519 nm->nm_prufn(nm->nm_so, nm->nm_m, nm->nm_flags));
522 void
523 netmsg_pru_send(netmsg_t msg)
525 struct netmsg_pru_send *nm = (void *)msg;
526 int error;
528 error = nm->nm_prufn(nm->nm_so, nm->nm_flags, nm->nm_m,
529 nm->nm_addr, nm->nm_control, nm->nm_td);
530 lwkt_replymsg(&msg->nm_lmsg, error);
533 void
534 netmsg_pru_sense(netmsg_t msg)
536 struct netmsg_pru_sense *nm = (void *)msg;
538 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_stat));
541 void
542 netmsg_pru_shutdown(netmsg_t msg)
544 struct netmsg_pru_shutdown *nm = (void *)msg;
546 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so));
549 void
550 netmsg_pru_sockaddr(netmsg_t msg)
552 struct netmsg_pru_sockaddr *nm = (void *)msg;
554 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_nam));
557 void
558 netmsg_pru_sopoll(netmsg_t msg)
560 struct netmsg_pru_sopoll *nm = (void *)msg;
561 int error;
563 error = nm->nm_prufn(nm->nm_so, nm->nm_events, nm->nm_cred, nm->nm_td);
564 lwkt_replymsg(&msg->nm_lmsg, error);
567 void
568 netmsg_pru_ctloutput(netmsg_t msg)
570 struct netmsg_pru_ctloutput *nm = (void *)msg;
572 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_sopt));
575 void
576 netmsg_pr_timeout(netmsg_t msg)
578 struct netmsg_pr_timeout *nm = (void *)msg;
580 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prfn());
584 * Handle a predicate event request. This function is only called once
585 * when the predicate message queueing request is received.
587 void
588 netmsg_so_notify(netmsg_t netmsg)
590 struct netmsg_so_notify *msg = (void *)netmsg;
591 struct signalsockbuf *ssb;
593 ssb = (msg->nm_etype & NM_REVENT) ?
594 &msg->nm_so->so_rcv :
595 &msg->nm_so->so_snd;
598 * Reply immediately if the event has occured, otherwise queue the
599 * request.
601 if (msg->nm_predicate(&msg->nm_netmsg)) {
602 lwkt_replymsg(&msg->nm_netmsg.nm_lmsg,
603 msg->nm_netmsg.nm_lmsg.ms_error);
604 } else {
605 TAILQ_INSERT_TAIL(&ssb->ssb_sel.si_mlist, msg, nm_list);
606 ssb->ssb_flags |= SSB_MEVENT;
611 * Called by doio when trying to abort a netmsg_so_notify message.
612 * Unlike the other functions this one is dispatched directly by
613 * the LWKT subsystem, so it takes a lwkt_msg_t as an argument.
615 * The original message, lmsg, is under the control of the caller and
616 * will not be destroyed until we return so we can safely reference it
617 * in our synchronous abort request.
619 * This part of the abort request occurs on the originating cpu which
620 * means we may race the message flags and the original message may
621 * not even have been processed by the target cpu yet.
623 void
624 netmsg_so_notify_doabort(lwkt_msg_t lmsg)
626 struct netmsg_so_notify_abort msg;
628 if ((lmsg->ms_flags & (MSGF_DONE | MSGF_REPLY)) == 0) {
629 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
630 netmsg_so_notify_abort);
631 msg.nm_notifymsg = (void *)lmsg;
632 lwkt_domsg(lmsg->ms_target_port, &msg.nm_netmsg.nm_lmsg, 0);
637 * Predicate requests can be aborted. This function is only called once
638 * and will interlock against processing/reply races (since such races
639 * occur on the same thread that controls the port where the abort is
640 * requeued).
642 * This part of the abort request occurs on the target cpu. The message
643 * flags must be tested again in case the test that we did on the
644 * originating cpu raced. Since messages are handled in sequence, the
645 * original message will have already been handled by the loop and either
646 * replied to or queued.
648 * We really only need to interlock with MSGF_REPLY (a bit that is set on
649 * our cpu when we reply). Note that MSGF_DONE is not set until the
650 * reply reaches the originating cpu. Test both bits anyway.
652 void
653 netmsg_so_notify_abort(netmsg_t netmsg)
655 struct netmsg_so_notify_abort *abrtmsg = (void *)netmsg;
656 struct netmsg_so_notify *msg = abrtmsg->nm_notifymsg;
657 struct signalsockbuf *ssb;
660 * The original notify message is not destroyed until after the
661 * abort request is returned, so we can check its state.
663 if ((msg->nm_netmsg.nm_lmsg.ms_flags & (MSGF_DONE | MSGF_REPLY)) == 0) {
664 ssb = (msg->nm_etype & NM_REVENT) ?
665 &msg->nm_so->so_rcv :
666 &msg->nm_so->so_snd;
667 TAILQ_REMOVE(&ssb->ssb_sel.si_mlist, msg, nm_list);
668 lwkt_replymsg(&msg->nm_netmsg.nm_lmsg, EINTR);
672 * Reply to the abort message
674 lwkt_replymsg(&abrtmsg->nm_netmsg.nm_lmsg, 0);