unp_connectat() set the flag, unp_connect_peer() cleared it on success,
and unp_connectat() cleared it again on error. Two clearers, each with
the same KASSERT, and a contract that only a comment held together. Now
the set and the clear sit in one function, a few lines apart, where they
can be read as the pair they are.
The obstacle was the lock: unp_connect_peer() cleared the flag while
holding locks the caller cannot easily retake, since for a connection
oriented socket the peer it ends up holding is a freshly cloned one the
caller never names.
So have it drop only the peer's lock and leave ours held, and let the
caller clear the flag on both outcomes. It does not lock on the caller's
behalf: on failure it returns having taken nothing, as it always did, and
the caller -- being the one that wants the lock -- takes it. That leaves
the function with no knowledge of what its caller means to do next, which
a second caller may well not share.
return_locked becomes return_peer_locked as a result. It never said
which of the two PCBs it governed, and the answer was both; now that our
own is always returned locked, it concerns only the peer, and can say so.
No functional change intended.
Signed-off-by: John Ericson <John.Ericson@Obsidian.Systems>
Assisted-by: Claude Code (Claude Opus 5)