+#if 0
+static int
+div_pcblist SYSCTL_HANDLER_ARGS
+{
+#pragma unused(oidp, arg1, arg2)
+ int error, i, n;
+ struct inpcb *inp, **inp_list;
+ inp_gen_t gencnt;
+ struct xinpgen xig;
+
+ /*
+ * The process of preparing the TCB list is too time-consuming and
+ * resource-intensive to repeat twice on every request.
+ */
+ lck_rw_lock_exclusive(divcbinfo.mtx);
+ if (req->oldptr == USER_ADDR_NULL) {
+ n = divcbinfo.ipi_count;
+ req->oldidx = 2 * (sizeof xig)
+ + (n + n/8) * sizeof(struct xinpcb);
+ lck_rw_done(divcbinfo.mtx);
+ return 0;
+ }
+
+ if (req->newptr != USER_ADDR_NULL) {
+ lck_rw_done(divcbinfo.mtx);
+ return EPERM;
+ }
+
+ /*
+ * OK, now we're committed to doing something.
+ */
+ gencnt = divcbinfo.ipi_gencnt;
+ n = divcbinfo.ipi_count;
+
+ bzero(&xig, sizeof(xig));
+ xig.xig_len = sizeof xig;
+ xig.xig_count = n;
+ xig.xig_gen = gencnt;
+ xig.xig_sogen = so_gencnt;
+ error = SYSCTL_OUT(req, &xig, sizeof xig);
+ if (error) {
+ lck_rw_done(divcbinfo.mtx);
+ return error;
+ }
+
+ inp_list = _MALLOC(n * sizeof *inp_list, M_TEMP, M_WAITOK);
+ if (inp_list == 0) {
+ lck_rw_done(divcbinfo.mtx);
+ return ENOMEM;
+ }
+
+ for (inp = LIST_FIRST(divcbinfo.listhead), i = 0; inp && i < n;
+ inp = LIST_NEXT(inp, inp_list)) {
+#ifdef __APPLE__
+ if (inp->inp_gencnt <= gencnt && inp->inp_state != INPCB_STATE_DEAD)
+#else
+ if (inp->inp_gencnt <= gencnt && !prison_xinpcb(req->p, inp))
+#endif
+ inp_list[i++] = inp;
+ }
+ n = i;
+
+ error = 0;
+ for (i = 0; i < n; i++) {
+ inp = inp_list[i];
+ if (inp->inp_gencnt <= gencnt && inp->inp_state != INPCB_STATE_DEAD) {
+ struct xinpcb xi;
+
+ bzero(&xi, sizeof(xi));
+ xi.xi_len = sizeof xi;
+ /* XXX should avoid extra copy */
+ inpcb_to_compat(inp, &xi.xi_inp);
+ if (inp->inp_socket)
+ sotoxsocket(inp->inp_socket, &xi.xi_socket);
+ error = SYSCTL_OUT(req, &xi, sizeof xi);
+ }
+ }
+ if (!error) {
+ /*
+ * Give the user an updated idea of our state.
+ * If the generation differs from what we told
+ * her before, she knows that something happened
+ * while we were processing this request, and it
+ * might be necessary to retry.
+ */
+ bzero(&xig, sizeof(xig));
+ xig.xig_len = sizeof xig;
+ xig.xig_gen = divcbinfo.ipi_gencnt;
+ xig.xig_sogen = so_gencnt;
+ xig.xig_count = divcbinfo.ipi_count;
+ error = SYSCTL_OUT(req, &xig, sizeof xig);
+ }
+ FREE(inp_list, M_TEMP);
+ lck_rw_done(divcbinfo.mtx);
+ return error;
+}
+#endif
+
+__private_extern__ int
+div_lock(struct socket *so, int refcount, void *lr)
+{
+ void *lr_saved;
+
+ if (lr == NULL)
+ lr_saved = __builtin_return_address(0);
+ else
+ lr_saved = lr;
+
+#ifdef MORE_DICVLOCK_DEBUG
+ printf("div_lock: so=%p sopcb=%p lock=%p ref=%x lr=%p\n",
+ so, so->so_pcb, so->so_pcb ?
+ &(((struct inpcb *)so->so_pcb)->inpcb_mtx) : NULL,
+ so->so_usecount, lr_saved);
+#endif
+ 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=%p sopcb=%p lock=%p ref=%x lr=%p\n",
+ so, so->so_pcb, so->so_pcb ?
+ &(((struct inpcb *)so->so_pcb)->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.mtx);
+ if (inp->inp_state != INPCB_STATE_DEAD)
+ in_pcbdetach(inp);
+ in_pcbdispose(inp);
+ lck_rw_done(divcbinfo.mtx);
+ 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 locktype)
+{
+ 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);
+ }
+}
+
+