MCPcopy Index your code
hub / github.com/F-Stack/f-stack / sofree

Function sofree

freebsd/kern/uipc_socket.c:1074–1167  ·  view source on GitHub ↗

* Evaluate the reference count and named references on a socket; if no * references remain, free it. This should be called whenever a reference is * released, such as in sorele(), but also when named reference flags are * cleared in socket or protocol code. * * sofree() will free the socket if: * * - There are no outstanding file descriptor references or related consumers * (so_count ==

Source from the content-addressed store, hash-verified

1072 * block in accept() despite select() saying the socket was ready.
1073 */
1074void
1075sofree(struct socket *so)
1076{
1077 struct protosw *pr = so->so_proto;
1078
1079 SOCK_LOCK_ASSERT(so);
1080
1081 if ((so->so_state & SS_NOFDREF) == 0 || so->so_count != 0 ||
1082 (so->so_state & SS_PROTOREF) || (so->so_qstate == SQ_COMP)) {
1083 SOCK_UNLOCK(so);
1084 return;
1085 }
1086
1087 if (!SOLISTENING(so) && so->so_qstate == SQ_INCOMP) {
1088 struct socket *sol;
1089
1090 sol = so->so_listen;
1091 KASSERT(sol, ("%s: so %p on incomp of NULL", __func__, so));
1092
1093 /*
1094 * To solve race between close of a listening socket and
1095 * a socket on its incomplete queue, we need to lock both.
1096 * The order is first listening socket, then regular.
1097 * Since we don't have SS_NOFDREF neither SS_PROTOREF, this
1098 * function and the listening socket are the only pointers
1099 * to so. To preserve so and sol, we reference both and then
1100 * relock.
1101 * After relock the socket may not move to so_comp since it
1102 * doesn't have PCB already, but it may be removed from
1103 * so_incomp. If that happens, we share responsiblity on
1104 * freeing the socket, but soclose() has already removed
1105 * it from queue.
1106 */
1107 soref(sol);
1108 soref(so);
1109 SOCK_UNLOCK(so);
1110 SOLISTEN_LOCK(sol);
1111 SOCK_LOCK(so);
1112 if (so->so_qstate == SQ_INCOMP) {
1113 KASSERT(so->so_listen == sol,
1114 ("%s: so %p migrated out of sol %p",
1115 __func__, so, sol));
1116 TAILQ_REMOVE(&sol->sol_incomp, so, so_list);
1117 sol->sol_incqlen--;
1118 /* This is guarenteed not to be the last. */
1119 refcount_release(&sol->so_count);
1120 so->so_qstate = SQ_NONE;
1121 so->so_listen = NULL;
1122 } else
1123 KASSERT(so->so_listen == NULL,
1124 ("%s: so %p not on (in)comp with so_listen",
1125 __func__, so));
1126 sorele(sol);
1127 KASSERT(so->so_count == 1,
1128 ("%s: so %p count %u", __func__, so, so->so_count));
1129 so->so_count = 0;
1130 }
1131 if (SOLISTENING(so))

Callers 4

tcp_twstartFunction · 0.85
tcp_twcloseFunction · 0.85
tcp_closeFunction · 0.85
soabortFunction · 0.85

Calls 5

refcount_releaseFunction · 0.85
sbdestroyFunction · 0.85
seldrainFunction · 0.85
knlist_destroyFunction · 0.85
sodeallocFunction · 0.85

Tested by

no test coverage detected