* Unconditionally schedule an inpcb to be freed by decrementing its * reference count, which should occur only after the inpcb has been detached * from its socket. If another thread holds a temporary reference (acquired * using in_pcbref()) then the free is deferred until that reference is * released using in_pcbrele(), but the inpcb is still unlocked. Almost all * work, including removal f
| 1862 | * the pcbinfo lock is held. |
| 1863 | */ |
| 1864 | void |
| 1865 | in_pcbfree(struct inpcb *inp) |
| 1866 | { |
| 1867 | struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; |
| 1868 | |
| 1869 | KASSERT(inp->inp_socket == NULL, ("%s: inp_socket != NULL", __func__)); |
| 1870 | KASSERT((inp->inp_flags2 & INP_FREED) == 0, |
| 1871 | ("%s: called twice for pcb %p", __func__, inp)); |
| 1872 | if (inp->inp_flags2 & INP_FREED) { |
| 1873 | INP_WUNLOCK(inp); |
| 1874 | return; |
| 1875 | } |
| 1876 | |
| 1877 | INP_WLOCK_ASSERT(inp); |
| 1878 | INP_LIST_WLOCK(pcbinfo); |
| 1879 | in_pcbremlists(inp); |
| 1880 | INP_LIST_WUNLOCK(pcbinfo); |
| 1881 | RO_INVALIDATE_CACHE(&inp->inp_route); |
| 1882 | /* mark as destruction in progress */ |
| 1883 | inp->inp_flags2 |= INP_FREED; |
| 1884 | INP_WUNLOCK(inp); |
| 1885 | NET_EPOCH_CALL(in_pcbfree_deferred, &inp->inp_epoch_ctx); |
| 1886 | } |
| 1887 | |
| 1888 | /* |
| 1889 | * in_pcbdrop() removes an inpcb from hashed lists, releasing its address and |
no test coverage detected