+static void
+tcp_garbage_collect(struct inpcb *inp, int istimewait)
+{
+ struct socket *so;
+ struct tcpcb *tp;
+
+ so = inp->inp_socket;
+ tp = intotcpcb(inp);
+
+ /*
+ * Skip if still in use or busy; it would have been more efficient
+ * if we were to test so_usecount against 0, but this isn't possible
+ * due to the current implementation of tcp_dropdropablreq() where
+ * overflow sockets that are eligible for garbage collection have
+ * their usecounts set to 1.
+ */
+ if (so->so_usecount > 1 || !lck_mtx_try_lock_spin(inp->inpcb_mtx))
+ return;
+
+ /* Check again under the lock */
+ if (so->so_usecount > 1) {
+ lck_mtx_unlock(inp->inpcb_mtx);
+ return;
+ }
+
+ /*
+ * Overflowed socket dropped from the listening queue? Do this
+ * only if we are called to clean up the time wait slots, since
+ * tcp_dropdropablreq() considers a socket to have been fully
+ * dropped after add_to_time_wait() is finished.
+ * Also handle the case of connections getting closed by the peer while in the queue as
+ * seen with rdar://6422317
+ *
+ */
+ if (so->so_usecount == 1 &&
+ ((istimewait && (so->so_flags & SOF_OVERFLOW)) ||
+ ((tp != NULL) && (tp->t_state == TCPS_CLOSED) && (so->so_head != NULL)
+ && ((so->so_state & (SS_INCOMP|SS_CANTSENDMORE|SS_CANTRCVMORE)) ==
+ (SS_INCOMP|SS_CANTSENDMORE|SS_CANTRCVMORE))))) {
+
+ if (inp->inp_state != INPCB_STATE_DEAD) {
+ /* Become a regular mutex */
+ lck_mtx_convert_spin(inp->inpcb_mtx);
+#if INET6
+ if (INP_CHECK_SOCKAF(so, AF_INET6))
+ in6_pcbdetach(inp);
+ else
+#endif /* INET6 */
+ in_pcbdetach(inp);
+ }
+ so->so_usecount--;
+ lck_mtx_unlock(inp->inpcb_mtx);
+ return;
+ } else if (inp->inp_wantcnt != WNT_STOPUSING) {
+ lck_mtx_unlock(inp->inpcb_mtx);
+ return;
+ }
+
+ /*
+ * We get here because the PCB is no longer searchable (WNT_STOPUSING);
+ * detach (if needed) and dispose if it is dead (usecount is 0). This
+ * covers all cases, including overflow sockets and those that are
+ * considered as "embryonic", i.e. created by sonewconn() in TCP input
+ * path, and have not yet been committed. For the former, we reduce
+ * the usecount to 0 as done by the code above. For the latter, the
+ * usecount would have reduced to 0 as part calling soabort() when the
+ * socket is dropped at the end of tcp_input().
+ */
+ if (so->so_usecount == 0) {
+ /* Become a regular mutex */
+ lck_mtx_convert_spin(inp->inpcb_mtx);
+ if (inp->inp_state != INPCB_STATE_DEAD) {
+#if INET6
+ if (INP_CHECK_SOCKAF(so, AF_INET6))
+ in6_pcbdetach(inp);
+ else
+#endif /* INET6 */
+ in_pcbdetach(inp);
+ }
+ in_pcbdispose(inp);
+ } else {
+ lck_mtx_unlock(inp->inpcb_mtx);
+ }
+}
+
+static int bg_cnt = 0;
+#define BG_COUNTER_MAX 3
+