* Wakeup processes waiting on a socket buffer. Do asynchronous notification * via SIGIO if the socket has the SS_ASYNC flag set. * * Called with the socket buffer lock held; will release the lock by the end * of the function. This allows the caller to acquire the socket buffer lock * while testing for the need for various sorts of wakeup and hold it through * to the point where it's no lon
| 492 | * correct. |
| 493 | */ |
| 494 | void |
| 495 | sowakeup(struct socket *so, struct sockbuf *sb) |
| 496 | { |
| 497 | int ret; |
| 498 | |
| 499 | SOCKBUF_LOCK_ASSERT(sb); |
| 500 | |
| 501 | selwakeuppri(sb->sb_sel, PSOCK); |
| 502 | if (!SEL_WAITING(sb->sb_sel)) |
| 503 | sb->sb_flags &= ~SB_SEL; |
| 504 | if (sb->sb_flags & SB_WAIT) { |
| 505 | sb->sb_flags &= ~SB_WAIT; |
| 506 | wakeup(&sb->sb_acc); |
| 507 | } |
| 508 | KNOTE_LOCKED(&sb->sb_sel->si_note, 0); |
| 509 | if (sb->sb_upcall != NULL) { |
| 510 | ret = sb->sb_upcall(so, sb->sb_upcallarg, M_NOWAIT); |
| 511 | if (ret == SU_ISCONNECTED) { |
| 512 | KASSERT(sb == &so->so_rcv, |
| 513 | ("SO_SND upcall returned SU_ISCONNECTED")); |
| 514 | soupcall_clear(so, SO_RCV); |
| 515 | } |
| 516 | } else |
| 517 | ret = SU_OK; |
| 518 | #ifndef FSTACK |
| 519 | if (sb->sb_flags & SB_AIO) |
| 520 | sowakeup_aio(so, sb); |
| 521 | #endif |
| 522 | SOCKBUF_UNLOCK(sb); |
| 523 | if (ret == SU_ISCONNECTED) |
| 524 | soisconnected(so); |
| 525 | if ((so->so_state & SS_ASYNC) && so->so_sigio != NULL) |
| 526 | pgsigio(&so->so_sigio, SIGIO, 0); |
| 527 | mtx_assert(SOCKBUF_MTX(sb), MA_NOTOWNED); |
| 528 | } |
| 529 | |
| 530 | /* |
| 531 | * Socket buffer (struct sockbuf) utility routines. |
nothing calls this directly
no test coverage detected