+ if (so->so_pcb) {
+ lck_mtx_lock(&((struct inpcb *)so->so_pcb)->inpcb_mtx);
+ } else {
+ panic("div_lock: so=%p NO PCB! lr=%p lrh= lrh= %s\n",
+ so, lr_saved, solockhistory_nr(so));
+ /* NOTREACHED */
+ }
+
+ if (so->so_usecount < 0) {
+ panic("div_lock: so=%p so_pcb=%p lr=%p ref=%x lrh= %s\n",
+ so, so->so_pcb, lr_saved, so->so_usecount,
+ solockhistory_nr(so));
+ /* NOTREACHED */
+ }
+
+ if (refcount)
+ so->so_usecount++;
+ so->lock_lr[so->next_lock_lr] = lr_saved;
+ so->next_lock_lr = (so->next_lock_lr+1) % SO_LCKDBG_MAX;
+
+ return (0);
+}
+
+__private_extern__ int
+div_unlock(struct socket *so, int refcount, void *lr)
+{
+ void *lr_saved;
+ lck_mtx_t * mutex_held;
+ struct inpcb *inp = sotoinpcb(so);
+
+ if (lr == NULL)
+ lr_saved = __builtin_return_address(0);
+ else
+ lr_saved = lr;
+
+#ifdef MORE_DICVLOCK_DEBUG
+ printf("div_unlock: so=0x%llx sopcb=0x%llx lock=0x%llx ref=%x "
+ "lr=0x%llx\n", (uint64_t)VM_KERNEL_ADDRPERM(so),
+ (uint64_t)VM_KERNEL_ADDRPERM(so->so_pcb), so->so_pcb ?
+ (uint64_t)VM_KERNEL_ADDRPERM(&(sotoinpcb(so)->inpcb_mtx)) : NULL,
+ so->so_usecount, lr_saved);
+#endif
+ if (refcount)
+ so->so_usecount--;
+
+ if (so->so_usecount < 0) {
+ panic("div_unlock: so=%p usecount=%x lrh= %s\n",
+ so, so->so_usecount, solockhistory_nr(so));
+ /* NOTREACHED */
+ }
+ if (so->so_pcb == NULL) {
+ panic("div_unlock: so=%p NO PCB usecount=%x lr=%p lrh= %s\n",
+ so, so->so_usecount, lr_saved, solockhistory_nr(so));
+ /* NOTREACHED */
+ }
+ mutex_held = &((struct inpcb *)so->so_pcb)->inpcb_mtx;
+
+ if (so->so_usecount == 0 && (inp->inp_wantcnt == WNT_STOPUSING)) {
+ lck_rw_lock_exclusive(divcbinfo.ipi_lock);
+ if (inp->inp_state != INPCB_STATE_DEAD)
+ in_pcbdetach(inp);
+ in_pcbdispose(inp);
+ lck_rw_done(divcbinfo.ipi_lock);
+ return (0);
+ }
+ LCK_MTX_ASSERT(mutex_held, LCK_MTX_ASSERT_OWNED);
+ so->unlock_lr[so->next_unlock_lr] = lr_saved;
+ so->next_unlock_lr = (so->next_unlock_lr+1) % SO_LCKDBG_MAX;
+ lck_mtx_unlock(mutex_held);
+ return (0);
+}
+
+__private_extern__ lck_mtx_t *
+div_getlock(struct socket *so, __unused int flags)
+{
+ struct inpcb *inpcb = (struct inpcb *)so->so_pcb;
+
+ if (so->so_pcb) {
+ if (so->so_usecount < 0)
+ panic("div_getlock: so=%p usecount=%x lrh= %s\n",
+ so, so->so_usecount, solockhistory_nr(so));
+ return(&inpcb->inpcb_mtx);
+ } else {
+ panic("div_getlock: so=%p NULL NO PCB lrh= %s\n",
+ so, solockhistory_nr(so));
+ return (so->so_proto->pr_domain->dom_mtx);
+ }
+}