mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-24 02:12:09 -05:00
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:
parent
6d7d9dd324
commit
01b3666894
2 changed files with 17 additions and 0 deletions
|
@ -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)
|
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));
|
dbgln_if(TCP_SOCKET_DEBUG, "TCPSocket({}) state moving from {} to {}", this, to_string(m_state), to_string(new_state));
|
||||||
|
|
|
@ -22,6 +22,8 @@ public:
|
||||||
static ErrorOr<NonnullRefPtr<TCPSocket>> try_create(int protocol, NonnullOwnPtr<DoubleBuffer> receive_buffer);
|
static ErrorOr<NonnullRefPtr<TCPSocket>> try_create(int protocol, NonnullOwnPtr<DoubleBuffer> receive_buffer);
|
||||||
virtual ~TCPSocket() override;
|
virtual ~TCPSocket() override;
|
||||||
|
|
||||||
|
virtual bool unref() const override;
|
||||||
|
|
||||||
enum class Direction {
|
enum class Direction {
|
||||||
Unspecified,
|
Unspecified,
|
||||||
Outgoing,
|
Outgoing,
|
||||||
|
|
Loading…
Add table
Reference in a new issue