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.13 2004/07/08 22:07:34 hsu 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 struct thread *td) 180 { 181 return ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, data, ifp, 182 td)); 183 #ifdef gag /* does copyin and copyout deep inside stack XXX JH */ 184 int error; 185 struct netmsg_pru_control msg; 186 lwkt_port_t port; 187 188 port = so->so_proto->pr_mport(so, NULL, PRU_CONTROL); 189 lwkt_initmsg(&msg.nm_lmsg, &curthread->td_msgport, 0, 190 lwkt_cmd_func(netmsg_pru_control), lwkt_cmd_op_none); 191 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_control; 192 msg.nm_so = so; 193 msg.nm_cmd = cmd; 194 msg.nm_data = data; 195 msg.nm_ifp = ifp; 196 msg.nm_td = td; 197 error = lwkt_domsg(port, &msg.nm_lmsg); 198 return (error); 199 #endif 200 } 201 202 int 203 so_pru_detach(struct socket *so) 204 { 205 int error; 206 struct netmsg_pru_detach msg; 207 lwkt_port_t port; 208 209 port = so->so_proto->pr_mport(so, NULL, PRU_DETACH); 210 lwkt_initmsg(&msg.nm_lmsg, &curthread->td_msgport, 0, 211 lwkt_cmd_func(netmsg_pru_detach), lwkt_cmd_op_none); 212 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_detach; 213 msg.nm_so = so; 214 error = lwkt_domsg(port, &msg.nm_lmsg); 215 return (error); 216 } 217 218 int 219 so_pru_disconnect(struct socket *so) 220 { 221 int error; 222 struct netmsg_pru_disconnect msg; 223 lwkt_port_t port; 224 225 port = so->so_proto->pr_mport(so, NULL, PRU_DISCONNECT); 226 lwkt_initmsg(&msg.nm_lmsg, &curthread->td_msgport, 0, 227 lwkt_cmd_func(netmsg_pru_disconnect), lwkt_cmd_op_none); 228 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_disconnect; 229 msg.nm_so = so; 230 error = lwkt_domsg(port, &msg.nm_lmsg); 231 return (error); 232 } 233 234 int 235 so_pru_listen(struct socket *so, struct thread *td) 236 { 237 int error; 238 struct netmsg_pru_listen msg; 239 lwkt_port_t port; 240 241 port = so->so_proto->pr_mport(so, NULL, PRU_LISTEN); 242 lwkt_initmsg(&msg.nm_lmsg, &curthread->td_msgport, 0, 243 lwkt_cmd_func(netmsg_pru_listen), lwkt_cmd_op_none); 244 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_listen; 245 msg.nm_so = so; 246 msg.nm_td = td; /* used only for prison_ip() XXX JH */ 247 error = lwkt_domsg(port, &msg.nm_lmsg); 248 return (error); 249 } 250 251 int 252 so_pru_peeraddr(struct socket *so, struct sockaddr **nam) 253 { 254 int error; 255 struct netmsg_pru_peeraddr msg; 256 lwkt_port_t port; 257 258 port = so->so_proto->pr_mport(so, NULL, PRU_PEERADDR); 259 lwkt_initmsg(&msg.nm_lmsg, &curthread->td_msgport, 0, 260 lwkt_cmd_func(netmsg_pru_peeraddr), lwkt_cmd_op_none); 261 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_peeraddr; 262 msg.nm_so = so; 263 msg.nm_nam = nam; 264 error = lwkt_domsg(port, &msg.nm_lmsg); 265 return (error); 266 } 267 268 int 269 so_pru_rcvd(struct socket *so, int flags) 270 { 271 int error; 272 struct netmsg_pru_rcvd msg; 273 lwkt_port_t port; 274 275 port = so->so_proto->pr_mport(so, NULL, PRU_RCVD); 276 lwkt_initmsg(&msg.nm_lmsg, &curthread->td_msgport, 0, 277 lwkt_cmd_func(netmsg_pru_rcvd), lwkt_cmd_op_none); 278 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_rcvd; 279 msg.nm_so = so; 280 msg.nm_flags = flags; 281 error = lwkt_domsg(port, &msg.nm_lmsg); 282 return (error); 283 } 284 285 int 286 so_pru_rcvoob(struct socket *so, struct mbuf *m, int flags) 287 { 288 int error; 289 struct netmsg_pru_rcvoob msg; 290 lwkt_port_t port; 291 292 port = so->so_proto->pr_mport(so, NULL, PRU_RCVOOB); 293 lwkt_initmsg(&msg.nm_lmsg, &curthread->td_msgport, 0, 294 lwkt_cmd_func(netmsg_pru_rcvoob), lwkt_cmd_op_none); 295 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_rcvoob; 296 msg.nm_so = so; 297 msg.nm_m = m; 298 msg.nm_flags = flags; 299 error = lwkt_domsg(port, &msg.nm_lmsg); 300 return (error); 301 } 302 303 int 304 so_pru_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, 305 struct mbuf *control, struct thread *td) 306 { 307 int error; 308 struct netmsg_pru_send msg; 309 lwkt_port_t port; 310 311 port = so->so_proto->pr_mport(so, NULL, PRU_SEND); 312 lwkt_initmsg(&msg.nm_lmsg, &curthread->td_msgport, 0, 313 lwkt_cmd_func(netmsg_pru_send), lwkt_cmd_op_none); 314 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_send; 315 msg.nm_so = so; 316 msg.nm_flags = flags; 317 msg.nm_m = m; 318 msg.nm_addr = addr; 319 msg.nm_control = control; 320 msg.nm_td = td; 321 error = lwkt_domsg(port, &msg.nm_lmsg); 322 return (error); 323 } 324 325 int 326 so_pru_sense(struct socket *so, struct stat *sb) 327 { 328 int error; 329 struct netmsg_pru_sense msg; 330 lwkt_port_t port; 331 332 port = so->so_proto->pr_mport(so, NULL, PRU_SENSE); 333 lwkt_initmsg(&msg.nm_lmsg, &curthread->td_msgport, 0, 334 lwkt_cmd_func(netmsg_pru_sense), lwkt_cmd_op_none); 335 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sense; 336 msg.nm_so = so; 337 msg.nm_stat = sb; 338 error = lwkt_domsg(port, &msg.nm_lmsg); 339 return (error); 340 } 341 342 int 343 so_pru_shutdown(struct socket *so) 344 { 345 int error; 346 struct netmsg_pru_shutdown msg; 347 lwkt_port_t port; 348 349 port = so->so_proto->pr_mport(so, NULL, PRU_SHUTDOWN); 350 lwkt_initmsg(&msg.nm_lmsg, &curthread->td_msgport, 0, 351 lwkt_cmd_func(netmsg_pru_shutdown), lwkt_cmd_op_none); 352 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_shutdown; 353 msg.nm_so = so; 354 error = lwkt_domsg(port, &msg.nm_lmsg); 355 return (error); 356 } 357 358 int 359 so_pru_sockaddr(struct socket *so, struct sockaddr **nam) 360 { 361 int error; 362 struct netmsg_pru_sockaddr msg; 363 lwkt_port_t port; 364 365 port = so->so_proto->pr_mport(so, NULL, PRU_SOCKADDR); 366 lwkt_initmsg(&msg.nm_lmsg, &curthread->td_msgport, 0, 367 lwkt_cmd_func(netmsg_pru_sockaddr), lwkt_cmd_op_none); 368 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sockaddr; 369 msg.nm_so = so; 370 msg.nm_nam = nam; 371 error = lwkt_domsg(port, &msg.nm_lmsg); 372 return (error); 373 } 374 375 int 376 so_pru_sopoll(struct socket *so, int events, struct ucred *cred, 377 struct thread *td) 378 { 379 int error; 380 struct netmsg_pru_sopoll msg; 381 lwkt_port_t port; 382 383 port = so->so_proto->pr_mport(so, NULL, PRU_SOPOLL); 384 lwkt_initmsg(&msg.nm_lmsg, &curthread->td_msgport, 0, 385 lwkt_cmd_func(netmsg_pru_sopoll), lwkt_cmd_op_none); 386 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sopoll; 387 msg.nm_so = so; 388 msg.nm_events = events; 389 msg.nm_cred = cred; 390 msg.nm_td = td; 391 error = lwkt_domsg(port, &msg.nm_lmsg); 392 return (error); 393 } 394 395 int 396 so_pr_ctloutput(struct socket *so, struct sockopt *sopt) 397 { 398 return ((*so->so_proto->pr_ctloutput)(so, sopt)); 399 #ifdef gag /* does copyin and copyout deep inside stack XXX JH */ 400 struct netmsg_pr_ctloutput msg; 401 lwkt_port_t port; 402 int error; 403 404 port = so->so_proto->pr_mport(so, NULL); 405 lwkt_initmsg(&msg.nm_lmsg, &curthread->td_msgport, 0, 406 lwkt_cmd_func(netmsg_pru_ctloutput), lwkt_cmd_op_none); 407 msg.nm_prfn = so->so_proto->pr_ctloutput; 408 msg.nm_so = so; 409 msg.nm_sopt = sopt; 410 error = lwkt_domsg(port, &msg.nm_lmsg); 411 return (error); 412 #endif 413 } 414 415 /* 416 * If we convert all the protosw pr_ functions for all the protocols 417 * to take a message directly, this layer can go away. For the moment 418 * our dispatcher ignores the return value, but since we are handling 419 * the replymsg ourselves we return EASYNC by convention. 420 */ 421 int 422 netmsg_pru_abort(lwkt_msg_t msg) 423 { 424 struct netmsg_pru_abort *nm = (void *)msg; 425 426 lwkt_replymsg(msg, nm->nm_prufn(nm->nm_so)); 427 return(EASYNC); 428 } 429 430 #ifdef notused 431 int 432 netmsg_pru_accept(lwkt_msg_t msg) 433 { 434 struct netmsg_pru_accept *nm = (void *)msg; 435 436 lwkt_replymsg(msg, nm->nm_prufn(nm->nm_so, nm->nm_nam)); 437 return(EASYNC); 438 } 439 #endif 440 441 int 442 netmsg_pru_attach(lwkt_msg_t msg) 443 { 444 struct netmsg_pru_attach *nm = (void *)msg; 445 446 lwkt_replymsg(msg, nm->nm_prufn(nm->nm_so, nm->nm_proto, nm->nm_ai)); 447 return(EASYNC); 448 } 449 450 int 451 netmsg_pru_bind(lwkt_msg_t msg) 452 { 453 struct netmsg_pru_bind *nm = (void *)msg; 454 455 lwkt_replymsg(msg, nm->nm_prufn(nm->nm_so, nm->nm_nam, nm->nm_td)); 456 return(EASYNC); 457 } 458 459 int 460 netmsg_pru_connect(lwkt_msg_t msg) 461 { 462 struct netmsg_pru_connect *nm = (void *)msg; 463 464 lwkt_replymsg(msg, nm->nm_prufn(nm->nm_so, nm->nm_nam, nm->nm_td)); 465 return(EASYNC); 466 } 467 468 int 469 netmsg_pru_connect2(lwkt_msg_t msg) 470 { 471 struct netmsg_pru_connect2 *nm = (void *)msg; 472 473 lwkt_replymsg(msg, nm->nm_prufn(nm->nm_so1, nm->nm_so2)); 474 return(EASYNC); 475 } 476 477 int 478 netmsg_pru_control(lwkt_msg_t msg) 479 { 480 struct netmsg_pru_control *nm = (void *)msg; 481 int error; 482 483 error = nm->nm_prufn(nm->nm_so, nm->nm_cmd, nm->nm_data, 484 nm->nm_ifp, nm->nm_td); 485 lwkt_replymsg(msg, error); 486 return(EASYNC); 487 } 488 489 int 490 netmsg_pru_detach(lwkt_msg_t msg) 491 { 492 struct netmsg_pru_detach *nm = (void *)msg; 493 494 lwkt_replymsg(msg, nm->nm_prufn(nm->nm_so)); 495 return(EASYNC); 496 } 497 498 int 499 netmsg_pru_disconnect(lwkt_msg_t msg) 500 { 501 struct netmsg_pru_disconnect *nm = (void *)msg; 502 503 lwkt_replymsg(msg, nm->nm_prufn(nm->nm_so)); 504 return(EASYNC); 505 } 506 507 int 508 netmsg_pru_listen(lwkt_msg_t msg) 509 { 510 struct netmsg_pru_listen *nm = (void *)msg; 511 512 lwkt_replymsg(msg, nm->nm_prufn(nm->nm_so, nm->nm_td)); 513 return(EASYNC); 514 } 515 516 int 517 netmsg_pru_peeraddr(lwkt_msg_t msg) 518 { 519 struct netmsg_pru_peeraddr *nm = (void *)msg; 520 521 lwkt_replymsg(msg, nm->nm_prufn(nm->nm_so, nm->nm_nam)); 522 return(EASYNC); 523 } 524 525 int 526 netmsg_pru_rcvd(lwkt_msg_t msg) 527 { 528 struct netmsg_pru_rcvd *nm = (void *)msg; 529 530 lwkt_replymsg(msg, nm->nm_prufn(nm->nm_so, nm->nm_flags)); 531 return(EASYNC); 532 } 533 534 int 535 netmsg_pru_rcvoob(lwkt_msg_t msg) 536 { 537 struct netmsg_pru_rcvoob *nm = (void *)msg; 538 539 lwkt_replymsg(msg, nm->nm_prufn(nm->nm_so, nm->nm_m, nm->nm_flags)); 540 return(EASYNC); 541 } 542 543 int 544 netmsg_pru_send(lwkt_msg_t msg) 545 { 546 struct netmsg_pru_send *nm = (void *)msg; 547 int error; 548 549 error = nm->nm_prufn(nm->nm_so, nm->nm_flags, nm->nm_m, 550 nm->nm_addr, nm->nm_control, nm->nm_td); 551 lwkt_replymsg(msg, error); 552 return(EASYNC); 553 } 554 555 int 556 netmsg_pru_sense(lwkt_msg_t msg) 557 { 558 struct netmsg_pru_sense *nm = (void *)msg; 559 560 lwkt_replymsg(msg, nm->nm_prufn(nm->nm_so, nm->nm_stat)); 561 return(EASYNC); 562 } 563 564 int 565 netmsg_pru_shutdown(lwkt_msg_t msg) 566 { 567 struct netmsg_pru_shutdown *nm = (void *)msg; 568 569 lwkt_replymsg(msg, nm->nm_prufn(nm->nm_so)); 570 return(EASYNC); 571 } 572 573 int 574 netmsg_pru_sockaddr(lwkt_msg_t msg) 575 { 576 struct netmsg_pru_sockaddr *nm = (void *)msg; 577 578 lwkt_replymsg(msg, nm->nm_prufn(nm->nm_so, nm->nm_nam)); 579 return(EASYNC); 580 } 581 582 int 583 netmsg_pru_sopoll(lwkt_msg_t msg) 584 { 585 struct netmsg_pru_sopoll *nm = (void *)msg; 586 int error; 587 588 error = nm->nm_prufn(nm->nm_so, nm->nm_events, nm->nm_cred, nm->nm_td); 589 lwkt_replymsg(msg, error); 590 return(EASYNC); 591 } 592 593 int 594 netmsg_pr_ctloutput(lwkt_msg_t msg) 595 { 596 struct netmsg_pr_ctloutput *nm = (void *)msg; 597 598 lwkt_replymsg(msg, nm->nm_prfn(nm->nm_so, nm->nm_sopt)); 599 return(EASYNC); 600 } 601 602 int 603 netmsg_pr_timeout(lwkt_msg_t msg) 604 { 605 struct netmsg_pr_timeout *nm = (void *)msg; 606 607 lwkt_replymsg(msg, nm->nm_prfn()); 608 return(EASYNC); 609 } 610 611 /* 612 * Handle a predicate event request. This function is only called once 613 * when the predicate message queueing request is received. 614 */ 615 int 616 netmsg_so_notify(lwkt_msg_t lmsg) 617 { 618 struct netmsg_so_notify *msg = (void *)lmsg; 619 struct sockbuf *sb; 620 621 sb = (msg->nm_etype & NM_REVENT) ? 622 &msg->nm_so->so_rcv : 623 &msg->nm_so->so_snd; 624 625 /* 626 * Reply immediately if the event has occured, otherwise queue the 627 * request. 628 */ 629 if (msg->nm_predicate((struct netmsg *)msg)) { 630 lwkt_replymsg(lmsg, lmsg->ms_error); 631 } else { 632 TAILQ_INSERT_TAIL(&sb->sb_sel.si_mlist, msg, nm_list); 633 sb->sb_flags |= SB_MEVENT; 634 } 635 return(EASYNC); 636 } 637 638 /* 639 * Predicate requests can be aborted. This function is only called once 640 * and will interlock against processing/reply races (since such races 641 * occur on the same thread that controls the port where the abort is 642 * requeued). 643 */ 644 int 645 netmsg_so_notify_abort(lwkt_msg_t lmsg) 646 { 647 struct netmsg_so_notify *msg = (void *)lmsg; 648 struct sockbuf *sb; 649 650 sb = (msg->nm_etype & NM_REVENT) ? 651 &msg->nm_so->so_rcv : 652 &msg->nm_so->so_snd; 653 TAILQ_REMOVE(&sb->sb_sel.si_mlist, msg, nm_list); 654 lwkt_replymsg(lmsg, EINTR); 655 return(EASYNC); 656 } 657 658