HAMMER Utilities: Sync with recent work.
[dragonfly.git] / sys / kern / uipc_msg.c
blobb4f3946792be225390186b63163c36d414d678c1
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.21 2008/06/17 20:50:11 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 <net/netmsg2.h>
49 #include <net/netisr.h>
50 #include <net/netmsg.h>
52 int
53 so_pru_abort(struct socket *so)
55 int error;
56 struct netmsg_pru_abort msg;
57 lwkt_port_t port;
59 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_ABORT);
60 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
61 netmsg_pru_abort);
62 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_abort;
63 msg.nm_so = so;
64 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
65 return (error);
68 int
69 so_pru_accept(struct socket *so, struct sockaddr **nam)
71 /* Block (memory allocation) in process context. XXX JH */
72 return ((*so->so_proto->pr_usrreqs->pru_accept)(so, nam));
74 #ifdef notdef
75 int error;
76 struct netmsg_pru_accept msg;
77 lwkt_port_t port;
79 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_ACCEPT);
80 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
81 netmsg_pru_accept);
82 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_accept;
83 msg.nm_so = so;
84 msg.nm_nam = nam;
85 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
86 return (error);
87 #endif
90 int
91 so_pru_attach(struct socket *so, int proto, struct pru_attach_info *ai)
93 int error;
94 struct netmsg_pru_attach msg;
95 lwkt_port_t port;
97 port = so->so_proto->pr_mport(NULL, NULL, NULL, PRU_ATTACH);
98 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
99 netmsg_pru_attach);
100 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_attach;
101 msg.nm_so = so;
102 msg.nm_proto = proto;
103 msg.nm_ai = ai;
104 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
105 return (error);
109 so_pru_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
111 int error;
112 struct netmsg_pru_bind msg;
113 lwkt_port_t port;
115 /* Send mesg to thread for new address. */
116 port = so->so_proto->pr_mport(NULL, nam, NULL, PRU_BIND);
117 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
118 netmsg_pru_bind);
119 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_bind;
120 msg.nm_so = so;
121 msg.nm_nam = nam;
122 msg.nm_td = td; /* used only for prison_ip() XXX JH */
123 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
124 return (error);
128 so_pru_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
130 int error;
131 struct netmsg_pru_connect msg;
132 lwkt_port_t port;
134 port = so->so_proto->pr_mport(so, nam, NULL, PRU_CONNECT);
135 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
136 netmsg_pru_connect);
137 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_connect;
138 msg.nm_so = so;
139 msg.nm_nam = nam;
140 msg.nm_td = td;
141 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
142 return (error);
146 so_pru_connect2(struct socket *so1, struct socket *so2)
148 int error;
149 struct netmsg_pru_connect2 msg;
150 lwkt_port_t port;
152 port = so1->so_proto->pr_mport(so1, NULL, NULL, PRU_CONNECT2);
153 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
154 netmsg_pru_connect2);
155 msg.nm_prufn = so1->so_proto->pr_usrreqs->pru_connect2;
156 msg.nm_so1 = so1;
157 msg.nm_so2 = so2;
158 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
159 return (error);
163 so_pru_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp)
165 return ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, data, ifp,
166 curthread));
167 #ifdef gag /* does copyin and copyout deep inside stack XXX JH */
168 int error;
169 struct netmsg_pru_control msg;
170 lwkt_port_t port;
172 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_CONTROL);
173 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
174 netmsg_pru_control);
175 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_control;
176 msg.nm_so = so;
177 msg.nm_cmd = cmd;
178 msg.nm_data = data;
179 msg.nm_ifp = ifp;
180 msg.nm_td = td;
181 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
182 return (error);
183 #endif
187 so_pru_detach(struct socket *so)
189 int error;
190 struct netmsg_pru_detach msg;
191 lwkt_port_t port;
193 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_DETACH);
194 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
195 netmsg_pru_detach);
196 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_detach;
197 msg.nm_so = so;
198 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
199 return (error);
203 so_pru_disconnect(struct socket *so)
205 int error;
206 struct netmsg_pru_disconnect msg;
207 lwkt_port_t port;
209 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_DISCONNECT);
210 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
211 netmsg_pru_disconnect);
212 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_disconnect;
213 msg.nm_so = so;
214 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
215 return (error);
219 so_pru_listen(struct socket *so, struct thread *td)
221 int error;
222 struct netmsg_pru_listen msg;
223 lwkt_port_t port;
225 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_LISTEN);
226 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
227 netmsg_pru_listen);
228 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_listen;
229 msg.nm_so = so;
230 msg.nm_td = td; /* used only for prison_ip() XXX JH */
231 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
232 return (error);
236 so_pru_peeraddr(struct socket *so, struct sockaddr **nam)
238 int error;
239 struct netmsg_pru_peeraddr msg;
240 lwkt_port_t port;
242 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_PEERADDR);
243 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
244 netmsg_pru_peeraddr);
245 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_peeraddr;
246 msg.nm_so = so;
247 msg.nm_nam = nam;
248 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
249 return (error);
253 so_pru_rcvd(struct socket *so, int flags)
255 int error;
256 struct netmsg_pru_rcvd msg;
257 lwkt_port_t port;
259 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_RCVD);
260 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
261 netmsg_pru_rcvd);
262 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_rcvd;
263 msg.nm_so = so;
264 msg.nm_flags = flags;
265 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
266 return (error);
270 so_pru_rcvoob(struct socket *so, struct mbuf *m, int flags)
272 int error;
273 struct netmsg_pru_rcvoob msg;
274 lwkt_port_t port;
276 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_RCVOOB);
277 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
278 netmsg_pru_rcvoob);
279 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_rcvoob;
280 msg.nm_so = so;
281 msg.nm_m = m;
282 msg.nm_flags = flags;
283 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
284 return (error);
288 so_pru_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
289 struct mbuf *control, struct thread *td)
291 int error;
292 struct netmsg_pru_send msg;
293 lwkt_port_t port;
295 port = so->so_proto->pr_mport(so, addr, &m, PRU_SEND);
296 if (port == NULL) {
297 KKASSERT(m == NULL);
298 return EINVAL;
301 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
302 netmsg_pru_send);
303 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_send;
304 msg.nm_so = so;
305 msg.nm_flags = flags;
306 msg.nm_m = m;
307 msg.nm_addr = addr;
308 msg.nm_control = control;
309 msg.nm_td = td;
310 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
311 return (error);
315 so_pru_sense(struct socket *so, struct stat *sb)
317 int error;
318 struct netmsg_pru_sense msg;
319 lwkt_port_t port;
321 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_SENSE);
322 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
323 netmsg_pru_sense);
324 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sense;
325 msg.nm_so = so;
326 msg.nm_stat = sb;
327 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
328 return (error);
332 so_pru_shutdown(struct socket *so)
334 int error;
335 struct netmsg_pru_shutdown msg;
336 lwkt_port_t port;
338 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_SHUTDOWN);
339 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
340 netmsg_pru_shutdown);
341 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_shutdown;
342 msg.nm_so = so;
343 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
344 return (error);
348 so_pru_sockaddr(struct socket *so, struct sockaddr **nam)
350 int error;
351 struct netmsg_pru_sockaddr msg;
352 lwkt_port_t port;
354 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_SOCKADDR);
355 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
356 netmsg_pru_sockaddr);
357 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sockaddr;
358 msg.nm_so = so;
359 msg.nm_nam = nam;
360 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
361 return (error);
365 so_pru_sopoll(struct socket *so, int events, struct ucred *cred)
367 int error;
368 struct netmsg_pru_sopoll msg;
369 lwkt_port_t port;
371 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_SOPOLL);
372 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
373 netmsg_pru_sopoll);
374 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sopoll;
375 msg.nm_so = so;
376 msg.nm_events = events;
377 msg.nm_cred = cred;
378 msg.nm_td = curthread;
379 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
380 return (error);
384 so_pru_ctloutput(struct socket *so, struct sockopt *sopt)
386 struct netmsg_pru_ctloutput msg;
387 lwkt_port_t port;
388 int error;
389 void *uval = NULL;
390 int need_copy;
392 need_copy = sopt->sopt_td != NULL;
393 if (need_copy) {
394 uval = sopt->sopt_val;
396 * we keep duplicate copies, but for option {s,g}etting
397 * who cares?
399 sopt->sopt_val = kmalloc(sopt->sopt_valsize, M_TEMP, M_WAITOK);
400 error = copyin(uval, sopt->sopt_val, sopt->sopt_valsize);
401 if (error)
402 goto out;
404 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_CTLOUTPUT);
405 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
406 netmsg_pru_ctloutput);
407 /* TBD: move pr_ctloutput to pr_usrreqs */
408 msg.nm_prufn = so->so_proto->pr_ctloutput;
409 msg.nm_so = so;
410 msg.nm_sopt = sopt;
411 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
412 out:
413 if (need_copy) {
414 if (!error) {
415 error = copyout(sopt->sopt_val, uval,
416 sopt->sopt_valsize);
419 * watch out: this may not be the same memory we allocated,
420 * callees "know" we're using M_TEMP so any reallocations
421 * will happen from there
423 kfree(sopt->sopt_val, M_TEMP);
424 sopt->sopt_val = uval;
426 return (error);
430 * If we convert all the protosw pr_ functions for all the protocols
431 * to take a message directly, this layer can go away. For the moment
432 * our dispatcher ignores the return value, but since we are handling
433 * the replymsg ourselves we return EASYNC by convention.
435 void
436 netmsg_pru_abort(netmsg_t msg)
438 struct netmsg_pru_abort *nm = (void *)msg;
440 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so));
443 #ifdef notused
444 void
445 netmsg_pru_accept(netmsg_t msg)
447 struct netmsg_pru_accept *nm = (void *)msg;
449 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_nam));
451 #endif
453 void
454 netmsg_pru_attach(netmsg_t msg)
456 struct netmsg_pru_attach *nm = (void *)msg;
458 lwkt_replymsg(&msg->nm_lmsg,
459 nm->nm_prufn(nm->nm_so, nm->nm_proto, nm->nm_ai));
462 void
463 netmsg_pru_bind(netmsg_t msg)
465 struct netmsg_pru_bind *nm = (void *)msg;
467 lwkt_replymsg(&msg->nm_lmsg,
468 nm->nm_prufn(nm->nm_so, nm->nm_nam, nm->nm_td));
471 void
472 netmsg_pru_connect(netmsg_t msg)
474 struct netmsg_pru_connect *nm = (void *)msg;
476 lwkt_replymsg(&msg->nm_lmsg,
477 nm->nm_prufn(nm->nm_so, nm->nm_nam, nm->nm_td));
480 void
481 netmsg_pru_connect2(netmsg_t msg)
483 struct netmsg_pru_connect2 *nm = (void *)msg;
485 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so1, nm->nm_so2));
488 void
489 netmsg_pru_control(netmsg_t msg)
491 struct netmsg_pru_control *nm = (void *)msg;
492 int error;
494 error = nm->nm_prufn(nm->nm_so, nm->nm_cmd, nm->nm_data,
495 nm->nm_ifp, nm->nm_td);
496 lwkt_replymsg(&msg->nm_lmsg, error);
499 void
500 netmsg_pru_detach(netmsg_t msg)
502 struct netmsg_pru_detach *nm = (void *)msg;
504 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so));
507 void
508 netmsg_pru_disconnect(netmsg_t msg)
510 struct netmsg_pru_disconnect *nm = (void *)msg;
512 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so));
515 void
516 netmsg_pru_listen(netmsg_t msg)
518 struct netmsg_pru_listen *nm = (void *)msg;
520 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_td));
523 void
524 netmsg_pru_peeraddr(netmsg_t msg)
526 struct netmsg_pru_peeraddr *nm = (void *)msg;
528 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_nam));
531 void
532 netmsg_pru_rcvd(netmsg_t msg)
534 struct netmsg_pru_rcvd *nm = (void *)msg;
536 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_flags));
539 void
540 netmsg_pru_rcvoob(netmsg_t msg)
542 struct netmsg_pru_rcvoob *nm = (void *)msg;
544 lwkt_replymsg(&msg->nm_lmsg,
545 nm->nm_prufn(nm->nm_so, nm->nm_m, nm->nm_flags));
548 void
549 netmsg_pru_send(netmsg_t msg)
551 struct netmsg_pru_send *nm = (void *)msg;
552 int error;
554 error = nm->nm_prufn(nm->nm_so, nm->nm_flags, nm->nm_m,
555 nm->nm_addr, nm->nm_control, nm->nm_td);
556 lwkt_replymsg(&msg->nm_lmsg, error);
559 void
560 netmsg_pru_sense(netmsg_t msg)
562 struct netmsg_pru_sense *nm = (void *)msg;
564 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_stat));
567 void
568 netmsg_pru_shutdown(netmsg_t msg)
570 struct netmsg_pru_shutdown *nm = (void *)msg;
572 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so));
575 void
576 netmsg_pru_sockaddr(netmsg_t msg)
578 struct netmsg_pru_sockaddr *nm = (void *)msg;
580 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_nam));
583 void
584 netmsg_pru_sopoll(netmsg_t msg)
586 struct netmsg_pru_sopoll *nm = (void *)msg;
587 int error;
589 error = nm->nm_prufn(nm->nm_so, nm->nm_events, nm->nm_cred, nm->nm_td);
590 lwkt_replymsg(&msg->nm_lmsg, error);
593 void
594 netmsg_pru_ctloutput(netmsg_t msg)
596 struct netmsg_pru_ctloutput *nm = (void *)msg;
598 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_sopt));
601 void
602 netmsg_pr_timeout(netmsg_t msg)
604 struct netmsg_pr_timeout *nm = (void *)msg;
606 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prfn());
610 * Handle a predicate event request. This function is only called once
611 * when the predicate message queueing request is received.
613 void
614 netmsg_so_notify(netmsg_t netmsg)
616 struct netmsg_so_notify *msg = (void *)netmsg;
617 struct signalsockbuf *ssb;
619 ssb = (msg->nm_etype & NM_REVENT) ?
620 &msg->nm_so->so_rcv :
621 &msg->nm_so->so_snd;
624 * Reply immediately if the event has occured, otherwise queue the
625 * request.
627 if (msg->nm_predicate(&msg->nm_netmsg)) {
628 lwkt_replymsg(&msg->nm_netmsg.nm_lmsg,
629 msg->nm_netmsg.nm_lmsg.ms_error);
630 } else {
631 TAILQ_INSERT_TAIL(&ssb->ssb_sel.si_mlist, msg, nm_list);
632 ssb->ssb_flags |= SSB_MEVENT;
637 * Called by doio when trying to abort a netmsg_so_notify message.
638 * Unlike the other functions this one is dispatched directly by
639 * the LWKT subsystem, so it takes a lwkt_msg_t as an argument.
641 * The original message, lmsg, is under the control of the caller and
642 * will not be destroyed until we return so we can safely reference it
643 * in our synchronous abort request.
645 * This part of the abort request occurs on the originating cpu which
646 * means we may race the message flags and the original message may
647 * not even have been processed by the target cpu yet.
649 void
650 netmsg_so_notify_doabort(lwkt_msg_t lmsg)
652 struct netmsg_so_notify_abort msg;
654 if ((lmsg->ms_flags & (MSGF_DONE | MSGF_REPLY)) == 0) {
655 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
656 netmsg_so_notify_abort);
657 msg.nm_notifymsg = (void *)lmsg;
658 lwkt_domsg(lmsg->ms_target_port, &msg.nm_netmsg.nm_lmsg, 0);
663 * Predicate requests can be aborted. This function is only called once
664 * and will interlock against processing/reply races (since such races
665 * occur on the same thread that controls the port where the abort is
666 * requeued).
668 * This part of the abort request occurs on the target cpu. The message
669 * flags must be tested again in case the test that we did on the
670 * originating cpu raced. Since messages are handled in sequence, the
671 * original message will have already been handled by the loop and either
672 * replied to or queued.
674 * We really only need to interlock with MSGF_REPLY (a bit that is set on
675 * our cpu when we reply). Note that MSGF_DONE is not set until the
676 * reply reaches the originating cpu. Test both bits anyway.
678 void
679 netmsg_so_notify_abort(netmsg_t netmsg)
681 struct netmsg_so_notify_abort *abrtmsg = (void *)netmsg;
682 struct netmsg_so_notify *msg = abrtmsg->nm_notifymsg;
683 struct signalsockbuf *ssb;
686 * The original notify message is not destroyed until after the
687 * abort request is returned, so we can check its state.
689 if ((msg->nm_netmsg.nm_lmsg.ms_flags & (MSGF_DONE | MSGF_REPLY)) == 0) {
690 ssb = (msg->nm_etype & NM_REVENT) ?
691 &msg->nm_so->so_rcv :
692 &msg->nm_so->so_snd;
693 TAILQ_REMOVE(&ssb->ssb_sel.si_mlist, msg, nm_list);
694 lwkt_replymsg(&msg->nm_netmsg.nm_lmsg, EINTR);
698 * Reply to the abort message
700 lwkt_replymsg(&abrtmsg->nm_netmsg.nm_lmsg, 0);