Kernel: Lock TCPSocket lookup table across destruction

Use the same trick as SlavePTY and override unref() to provide safe
removal from the sockets_by_tuple table when destroying a TCPSocket.

This should fix the TCPSocket::from_tuple() flake seen on CI.
This commit is contained in:
Andreas Kling 2022-01-06 22:06:00 +01:00
parent 6d7d9dd324
commit 01b3666894
Notes: sideshowbarker 2024-07-17 21:31:47 +09:00
2 changed files with 17 additions and 0 deletions

View File

@ -29,6 +29,21 @@ void TCPSocket::for_each(Function<void(const TCPSocket&)> callback)
});
}
bool TCPSocket::unref() const
{
bool did_hit_zero = sockets_by_tuple().with_exclusive([&](auto& table) {
if (deref_base())
return false;
table.remove(tuple());
return true;
});
if (did_hit_zero) {
const_cast<TCPSocket&>(*this).will_be_destroyed();
delete this;
}
return did_hit_zero;
}
void TCPSocket::set_state(State new_state)
{
dbgln_if(TCP_SOCKET_DEBUG, "TCPSocket({}) state moving from {} to {}", this, to_string(m_state), to_string(new_state));

View File

@ -22,6 +22,8 @@ public:
static ErrorOr<NonnullRefPtr<TCPSocket>> try_create(int protocol, NonnullOwnPtr<DoubleBuffer> receive_buffer);
virtual ~TCPSocket() override;
virtual bool unref() const override;
enum class Direction {
Unspecified,
Outgoing,