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