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. 19 * 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. 32 * 33 * $DragonFly: src/sys/kern/uipc_msg.c,v 1.16 2007/04/22 01:13:10 dillon Exp $ 34 */ 35 36 #include <sys/param.h> 37 #include <sys/systm.h> 38 #include <sys/msgport.h> 39 #include <sys/protosw.h> 40 #include <sys/socket.h> 41 #include <sys/socketvar.h> 42 #include <sys/socketops.h> 43 #include <sys/thread.h> 44 #include <sys/thread2.h> 45 #include <sys/msgport2.h> 46 47 #include <net/netisr.h> 48 #include <net/netmsg.h> 49 50 int 51 so_pru_abort(struct socket *so) 52 { 53 int error; 54 struct netmsg_pru_abort msg; 55 lwkt_port_t port; 56 57 port = so->so_proto->pr_mport(so, NULL, PRU_ABORT); 58 lwkt_initmsg(&msg.nm_lmsg, &curthread->td_msgport, 0, 59 lwkt_cmd_func(netmsg_pru_abort), lwkt_cmd_op_none); 60 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_abort; 61 msg.nm_so = so; 62 error = lwkt_domsg(port, &msg.nm_lmsg); 63 return (error); 64 } 65 66 int 67 so_pru_accept(struct socket *so, struct sockaddr **nam) 68 { 69 /* Block (memory allocation) in process context. XXX JH */ 70 return ((*so->so_proto->pr_usrreqs->pru_accept)(so, nam)); 71 72 #ifdef notdef 73 int error; 74 struct netmsg_pru_accept msg; 75 lwkt_port_t port; 76 77 port = so->so_proto->pr_mport(so, NULL, PRU_ACCEPT); 78 lwkt_initmsg(&msg.nm_lmsg, &curthread->td_msgport, 0, 79 lwkt_cmd_func(netmsg_pru_accept), lwkt_cmd_op_none); 80 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_accept; 81 msg.nm_so = so; 82 msg.nm_nam = nam; 83 error = lwkt_domsg(port, &msg.nm_lmsg); 84 return (error); 85 #endif 86 } 87 88 int 89 so_pru_attach(struct socket *so, int proto, struct pru_attach_info *ai) 90 { 91 int error; 92 struct netmsg_pru_attach msg; 93 lwkt_port_t port; 94 95 port = so->so_proto->pr_mport(NULL, NULL, PRU_ATTACH); 96 lwkt_initmsg(&msg.nm_lmsg, &curthread->td_msgport, 0, 97 lwkt_cmd_func(netmsg_pru_attach), lwkt_cmd_op_none); 98 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_attach; 99 msg.nm_so = so; 100 msg.nm_proto = proto; 101 msg.nm_ai = ai; 102 error = lwkt_domsg(port, &msg.nm_lmsg); 103 return (error); 104 } 105 106 int 107 so_pru_bind(struct socket *so, struct sockaddr *nam, struct thread *td) 108 { 109 int error; 110 struct netmsg_pru_bind msg; 111 lwkt_port_t port; 112 113 /* Send mesg to thread for new address. */ 114 port = so->so_proto->pr_mport(NULL, nam, PRU_BIND); 115 lwkt_initmsg(&msg.nm_lmsg, &curthread->td_msgport, 0, 116 lwkt_cmd_func(netmsg_pru_bind), lwkt_cmd_op_none); 117 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_bind; 118 msg.nm_so = so; 119 msg.nm_nam = nam; 120 msg.nm_td = td; /* used only for prison_ip() XXX JH */ 121 error = lwkt_domsg(port, &msg.nm_lmsg); 122 return (error); 123 } 124 125 int 126 so_pru_connect(struct socket *so, struct sockaddr *nam, struct thread *td) 127 { 128 int error; 129 struct netmsg_pru_connect msg; 130 lwkt_port_t port; 131 132 port = so->so_proto->pr_mport(so, nam, PRU_CONNECT); 133 lwkt_initmsg(&msg.nm_lmsg, &curthread->td_msgport, 0, 134 lwkt_cmd_func(netmsg_pru_connect), lwkt_cmd_op_none); 135 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_connect; 136 msg.nm_so = so; 137 msg.nm_nam = nam; 138 msg.nm_td = td; 139 error = lwkt_domsg(port, &msg.nm_lmsg); 140 return (error); 141 } 142 143 int 144 so_pru_connect2(struct socket *so1, struct socket *so2) 145 { 146 int error; 147 struct netmsg_pru_connect2 msg; 148 lwkt_port_t port; 149 150 port = so1->so_proto->pr_mport(so1, NULL, PRU_CONNECT2); 151 lwkt_initmsg(&msg.nm_lmsg, &curthread->td_msgport, 0, 152 lwkt_cmd_func(netmsg_pru_connect2), lwkt_cmd_op_none); 153 msg.nm_prufn = so1->so_proto->pr_usrreqs->pru_connect2; 154 msg.nm_so1 = so1; 155 msg.nm_so2 = so2; 156 error = lwkt_domsg(port, &msg.nm_lmsg); 157 return (error); 158 } 159 160 int 161 so_pru_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp) 162 { 163 return ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, data, ifp, 164 curthread)); 165 #ifdef gag /* does copyin and copyout deep inside stack XXX JH */ 166 int error; 167 struct netmsg_pru_control msg; 168 lwkt_port_t port; 169 170 port = so->so_proto->pr_mport(so, NULL, PRU_CONTROL); 171 lwkt_initmsg(&msg.nm_lmsg, &curthread->td_msgport, 0, 172 lwkt_cmd_func(netmsg_pru_control), lwkt_cmd_op_none); 173 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_control; 174 msg.nm_so = so; 175 msg.nm_cmd = cmd; 176 msg.nm_data = data; 177 msg.nm_ifp = ifp; 178 msg.nm_td = td; 179 error = lwkt_domsg(port, &msg.nm_lmsg); 180 return (error); 181 #endif 182 } 183 184 int 185 so_pru_detach(struct socket *so) 186 { 187 int error; 188 struct netmsg_pru_detach msg; 189 lwkt_port_t port; 190 191 port = so->so_proto->pr_mport(so, NULL, PRU_DETACH); 192 lwkt_initmsg(&msg.nm_lmsg, &curthread->td_msgport, 0, 193 lwkt_cmd_func(netmsg_pru_detach), lwkt_cmd_op_none); 194 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_detach; 195 msg.nm_so = so; 196 error = lwkt_domsg(port, &msg.nm_lmsg); 197 return (error); 198 } 199 200 int 201 so_pru_disconnect(struct socket *so) 202 { 203 int error; 204 struct netmsg_pru_disconnect msg; 205 lwkt_port_t port; 206 207 port = so->so_proto->pr_mport(so, NULL, PRU_DISCONNECT); 208 lwkt_initmsg(&msg.nm_lmsg, &curthread->td_msgport, 0, 209 lwkt_cmd_func(netmsg_pru_disconnect), lwkt_cmd_op_none); 210 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_disconnect; 211 msg.nm_so = so; 212 error = lwkt_domsg(port, &msg.nm_lmsg); 213 return (error); 214 } 215 216 int 217 so_pru_listen(struct socket *so, struct thread *td) 218 { 219 int error; 220 struct netmsg_pru_listen msg; 221 lwkt_port_t port; 222 223 port = so->so_proto->pr_mport(so, NULL, PRU_LISTEN); 224 lwkt_initmsg(&msg.nm_lmsg, &curthread->td_msgport, 0, 225 lwkt_cmd_func(netmsg_pru_listen), lwkt_cmd_op_none); 226 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_listen; 227 msg.nm_so = so; 228 msg.nm_td = td; /* used only for prison_ip() XXX JH */ 229 error = lwkt_domsg(port, &msg.nm_lmsg); 230 return (error); 231 } 232 233 int 234 so_pru_peeraddr(struct socket *so, struct sockaddr **nam) 235 { 236 int error; 237 struct netmsg_pru_peeraddr msg; 238 lwkt_port_t port; 239 240 port = so->so_proto->pr_mport(so, NULL, PRU_PEERADDR); 241 lwkt_initmsg(&msg.nm_lmsg, &curthread->td_msgport, 0, 242 lwkt_cmd_func(netmsg_pru_peeraddr), lwkt_cmd_op_none); 243 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_peeraddr; 244 msg.nm_so = so; 245 msg.nm_nam = nam; 246 error = lwkt_domsg(port, &msg.nm_lmsg); 247 return (error); 248 } 249 250 int 251 so_pru_rcvd(struct socket *so, int flags) 252 { 253 int error; 254 struct netmsg_pru_rcvd msg; 255 lwkt_port_t port; 256 257 port = so->so_proto->pr_mport(so, NULL, PRU_RCVD); 258 lwkt_initmsg(&msg.nm_lmsg, &curthread->td_msgport, 0, 259 lwkt_cmd_func(netmsg_pru_rcvd), lwkt_cmd_op_none); 260 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_rcvd; 261 msg.nm_so = so; 262 msg.nm_flags = flags; 263 error = lwkt_domsg(port, &msg.nm_lmsg); 264 return (error); 265 } 266 267 int 268 so_pru_rcvoob(struct socket *so, struct mbuf *m, int flags) 269 { 270 int error; 271 struct netmsg_pru_rcvoob msg; 272 lwkt_port_t port; 273 274 port = so->so_proto->pr_mport(so, NULL, PRU_RCVOOB); 275 lwkt_initmsg(&msg.nm_lmsg, &curthread->td_msgport, 0, 276 lwkt_cmd_func(netmsg_pru_rcvoob), lwkt_cmd_op_none); 277 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_rcvoob; 278 msg.nm_so = so; 279 msg.nm_m = m; 280 msg.nm_flags = flags; 281 error = lwkt_domsg(port, &msg.nm_lmsg); 282 return (error); 283 } 284 285 int 286 so_pru_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, 287 struct mbuf *control, struct thread *td) 288 { 289 int error; 290 struct netmsg_pru_send msg; 291 lwkt_port_t port; 292 293 port = so->so_proto->pr_mport(so, NULL, PRU_SEND); 294 lwkt_initmsg(&msg.nm_lmsg, &curthread->td_msgport, 0, 295 lwkt_cmd_func(netmsg_pru_send), lwkt_cmd_op_none); 296 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_send; 297 msg.nm_so = so; 298 msg.nm_flags = flags; 299 msg.nm_m = m; 300 msg.nm_addr = addr; 301 msg.nm_control = control; 302 msg.nm_td = td; 303 error = lwkt_domsg(port, &msg.nm_lmsg); 304 return (error); 305 } 306 307 int 308 so_pru_sense(struct socket *so, struct stat *sb) 309 { 310 int error; 311 struct netmsg_pru_sense msg; 312 lwkt_port_t port; 313 314 port = so->so_proto->pr_mport(so, NULL, PRU_SENSE); 315 lwkt_initmsg(&msg.nm_lmsg, &curthread->td_msgport, 0, 316 lwkt_cmd_func(netmsg_pru_sense), lwkt_cmd_op_none); 317 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sense; 318 msg.nm_so = so; 319 msg.nm_stat = sb; 320 error = lwkt_domsg(port, &msg.nm_lmsg); 321 return (error); 322 } 323 324 int 325 so_pru_shutdown(struct socket *so) 326 { 327 int error; 328 struct netmsg_pru_shutdown msg; 329 lwkt_port_t port; 330 331 port = so->so_proto->pr_mport(so, NULL, PRU_SHUTDOWN); 332 lwkt_initmsg(&msg.nm_lmsg, &curthread->td_msgport, 0, 333 lwkt_cmd_func(netmsg_pru_shutdown), lwkt_cmd_op_none); 334 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_shutdown; 335 msg.nm_so = so; 336 error = lwkt_domsg(port, &msg.nm_lmsg); 337 return (error); 338 } 339 340 int 341 so_pru_sockaddr(struct socket *so, struct sockaddr **nam) 342 { 343 int error; 344 struct netmsg_pru_sockaddr msg; 345 lwkt_port_t port; 346 347 port = so->so_proto->pr_mport(so, NULL, PRU_SOCKADDR); 348 lwkt_initmsg(&msg.nm_lmsg, &curthread->td_msgport, 0, 349 lwkt_cmd_func(netmsg_pru_sockaddr), lwkt_cmd_op_none); 350 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sockaddr; 351 msg.nm_so = so; 352 msg.nm_nam = nam; 353 error = lwkt_domsg(port, &msg.nm_lmsg); 354 return (error); 355 } 356 357 int 358 so_pru_sopoll(struct socket *so, int events, struct ucred *cred) 359 { 360 int error; 361 struct netmsg_pru_sopoll msg; 362 lwkt_port_t port; 363 364 port = so->so_proto->pr_mport(so, NULL, PRU_SOPOLL); 365 lwkt_initmsg(&msg.nm_lmsg, &curthread->td_msgport, 0, 366 lwkt_cmd_func(netmsg_pru_sopoll), lwkt_cmd_op_none); 367 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sopoll; 368 msg.nm_so = so; 369 msg.nm_events = events; 370 msg.nm_cred = cred; 371 msg.nm_td = curthread; 372 error = lwkt_domsg(port, &msg.nm_lmsg); 373 return (error); 374 } 375 376 int 377 so_pr_ctloutput(struct socket *so, struct sockopt *sopt) 378 { 379 return ((*so->so_proto->pr_ctloutput)(so, sopt)); 380 #ifdef gag /* does copyin and copyout deep inside stack XXX JH */ 381 struct netmsg_pr_ctloutput msg; 382 lwkt_port_t port; 383 int error; 384 385 port = so->so_proto->pr_mport(so, NULL); 386 lwkt_initmsg(&msg.nm_lmsg, &curthread->td_msgport, 0, 387 lwkt_cmd_func(netmsg_pru_ctloutput), lwkt_cmd_op_none); 388 msg.nm_prfn = so->so_proto->pr_ctloutput; 389 msg.nm_so = so; 390 msg.nm_sopt = sopt; 391 error = lwkt_domsg(port, &msg.nm_lmsg); 392 return (error); 393 #endif 394 } 395 396 /* 397 * If we convert all the protosw pr_ functions for all the protocols 398 * to take a message directly, this layer can go away. For the moment 399 * our dispatcher ignores the return value, but since we are handling 400 * the replymsg ourselves we return EASYNC by convention. 401 */ 402 int 403 netmsg_pru_abort(lwkt_msg_t msg) 404 { 405 struct netmsg_pru_abort *nm = (void *)msg; 406 407 lwkt_replymsg(msg, nm->nm_prufn(nm->nm_so)); 408 return(EASYNC); 409 } 410 411 #ifdef notused 412 int 413 netmsg_pru_accept(lwkt_msg_t msg) 414 { 415 struct netmsg_pru_accept *nm = (void *)msg; 416 417 lwkt_replymsg(msg, nm->nm_prufn(nm->nm_so, nm->nm_nam)); 418 return(EASYNC); 419 } 420 #endif 421 422 int 423 netmsg_pru_attach(lwkt_msg_t msg) 424 { 425 struct netmsg_pru_attach *nm = (void *)msg; 426 427 lwkt_replymsg(msg, nm->nm_prufn(nm->nm_so, nm->nm_proto, nm->nm_ai)); 428 return(EASYNC); 429 } 430 431 int 432 netmsg_pru_bind(lwkt_msg_t msg) 433 { 434 struct netmsg_pru_bind *nm = (void *)msg; 435 436 lwkt_replymsg(msg, nm->nm_prufn(nm->nm_so, nm->nm_nam, nm->nm_td)); 437 return(EASYNC); 438 } 439 440 int 441 netmsg_pru_connect(lwkt_msg_t msg) 442 { 443 struct netmsg_pru_connect *nm = (void *)msg; 444 445 lwkt_replymsg(msg, nm->nm_prufn(nm->nm_so, nm->nm_nam, nm->nm_td)); 446 return(EASYNC); 447 } 448 449 int 450 netmsg_pru_connect2(lwkt_msg_t msg) 451 { 452 struct netmsg_pru_connect2 *nm = (void *)msg; 453 454 lwkt_replymsg(msg, nm->nm_prufn(nm->nm_so1, nm->nm_so2)); 455 return(EASYNC); 456 } 457 458 int 459 netmsg_pru_control(lwkt_msg_t msg) 460 { 461 struct netmsg_pru_control *nm = (void *)msg; 462 int error; 463 464 error = nm->nm_prufn(nm->nm_so, nm->nm_cmd, nm->nm_data, 465 nm->nm_ifp, nm->nm_td); 466 lwkt_replymsg(msg, error); 467 return(EASYNC); 468 } 469 470 int 471 netmsg_pru_detach(lwkt_msg_t msg) 472 { 473 struct netmsg_pru_detach *nm = (void *)msg; 474 475 lwkt_replymsg(msg, nm->nm_prufn(nm->nm_so)); 476 return(EASYNC); 477 } 478 479 int 480 netmsg_pru_disconnect(lwkt_msg_t msg) 481 { 482 struct netmsg_pru_disconnect *nm = (void *)msg; 483 484 lwkt_replymsg(msg, nm->nm_prufn(nm->nm_so)); 485 return(EASYNC); 486 } 487 488 int 489 netmsg_pru_listen(lwkt_msg_t msg) 490 { 491 struct netmsg_pru_listen *nm = (void *)msg; 492 493 lwkt_replymsg(msg, nm->nm_prufn(nm->nm_so, nm->nm_td)); 494 return(EASYNC); 495 } 496 497 int 498 netmsg_pru_peeraddr(lwkt_msg_t msg) 499 { 500 struct netmsg_pru_peeraddr *nm = (void *)msg; 501 502 lwkt_replymsg(msg, nm->nm_prufn(nm->nm_so, nm->nm_nam)); 503 return(EASYNC); 504 } 505 506 int 507 netmsg_pru_rcvd(lwkt_msg_t msg) 508 { 509 struct netmsg_pru_rcvd *nm = (void *)msg; 510 511 lwkt_replymsg(msg, nm->nm_prufn(nm->nm_so, nm->nm_flags)); 512 return(EASYNC); 513 } 514 515 int 516 netmsg_pru_rcvoob(lwkt_msg_t msg) 517 { 518 struct netmsg_pru_rcvoob *nm = (void *)msg; 519 520 lwkt_replymsg(msg, nm->nm_prufn(nm->nm_so, nm->nm_m, nm->nm_flags)); 521 return(EASYNC); 522 } 523 524 int 525 netmsg_pru_send(lwkt_msg_t msg) 526 { 527 struct netmsg_pru_send *nm = (void *)msg; 528 int error; 529 530 error = nm->nm_prufn(nm->nm_so, nm->nm_flags, nm->nm_m, 531 nm->nm_addr, nm->nm_control, nm->nm_td); 532 lwkt_replymsg(msg, error); 533 return(EASYNC); 534 } 535 536 int 537 netmsg_pru_sense(lwkt_msg_t msg) 538 { 539 struct netmsg_pru_sense *nm = (void *)msg; 540 541 lwkt_replymsg(msg, nm->nm_prufn(nm->nm_so, nm->nm_stat)); 542 return(EASYNC); 543 } 544 545 int 546 netmsg_pru_shutdown(lwkt_msg_t msg) 547 { 548 struct netmsg_pru_shutdown *nm = (void *)msg; 549 550 lwkt_replymsg(msg, nm->nm_prufn(nm->nm_so)); 551 return(EASYNC); 552 } 553 554 int 555 netmsg_pru_sockaddr(lwkt_msg_t msg) 556 { 557 struct netmsg_pru_sockaddr *nm = (void *)msg; 558 559 lwkt_replymsg(msg, nm->nm_prufn(nm->nm_so, nm->nm_nam)); 560 return(EASYNC); 561 } 562 563 int 564 netmsg_pru_sopoll(lwkt_msg_t msg) 565 { 566 struct netmsg_pru_sopoll *nm = (void *)msg; 567 int error; 568 569 error = nm->nm_prufn(nm->nm_so, nm->nm_events, nm->nm_cred, nm->nm_td); 570 lwkt_replymsg(msg, error); 571 return(EASYNC); 572 } 573 574 int 575 netmsg_pr_ctloutput(lwkt_msg_t msg) 576 { 577 struct netmsg_pr_ctloutput *nm = (void *)msg; 578 579 lwkt_replymsg(msg, nm->nm_prfn(nm->nm_so, nm->nm_sopt)); 580 return(EASYNC); 581 } 582 583 int 584 netmsg_pr_timeout(lwkt_msg_t msg) 585 { 586 struct netmsg_pr_timeout *nm = (void *)msg; 587 588 lwkt_replymsg(msg, nm->nm_prfn()); 589 return(EASYNC); 590 } 591 592 /* 593 * Handle a predicate event request. This function is only called once 594 * when the predicate message queueing request is received. 595 */ 596 int 597 netmsg_so_notify(lwkt_msg_t lmsg) 598 { 599 struct netmsg_so_notify *msg = (void *)lmsg; 600 struct signalsockbuf *ssb; 601 602 ssb = (msg->nm_etype & NM_REVENT) ? 603 &msg->nm_so->so_rcv : 604 &msg->nm_so->so_snd; 605 606 /* 607 * Reply immediately if the event has occured, otherwise queue the 608 * request. 609 */ 610 if (msg->nm_predicate((struct netmsg *)msg)) { 611 lwkt_replymsg(lmsg, lmsg->ms_error); 612 } else { 613 TAILQ_INSERT_TAIL(&ssb->ssb_sel.si_mlist, msg, nm_list); 614 ssb->ssb_flags |= SSB_MEVENT; 615 } 616 return(EASYNC); 617 } 618 619 /* 620 * Predicate requests can be aborted. This function is only called once 621 * and will interlock against processing/reply races (since such races 622 * occur on the same thread that controls the port where the abort is 623 * requeued). 624 */ 625 int 626 netmsg_so_notify_abort(lwkt_msg_t lmsg) 627 { 628 struct netmsg_so_notify *msg = (void *)lmsg; 629 struct signalsockbuf *ssb; 630 631 ssb = (msg->nm_etype & NM_REVENT) ? 632 &msg->nm_so->so_rcv : 633 &msg->nm_so->so_snd; 634 TAILQ_REMOVE(&ssb->ssb_sel.si_mlist, msg, nm_list); 635 lwkt_replymsg(lmsg, EINTR); 636 return(EASYNC); 637 } 638 639