diff options
| author | cirakg <cirakg@cirakg.xyz> | 2026-11-03 00:46:55 +0100 |
|---|---|---|
| committer | cirakg <cirakg@cirakg.xyz> | 2026-11-03 00:46:55 +0100 |
| commit | 36d3d002e5bd75596b8cf00c1115632a5ae8976a (patch) | |
| tree | fb4c0238d24e2daab253dd4f209679bc3baf68ca /src/core/hle/service/sockets/bsd.h | |
| parent | 2aa4b29c4544593cfe3d61f0db0ad45b58af4b28 (diff) | |
network: keep bsd sockets alive across concurrent close and fix room gaps
bsd runs on three host threads, but its calls kept a raw reference into
the shared descriptor table while they used a socket. A close() on
another thread could then destroy the socket mid-call. Waking a blocked
room recv() on close made this happen every time. Every call now works
on a copy of the descriptor taken under the table lock, poll() keeps its
sockets alive while it waits, and close() resets the slot only if it
still holds the same socket.
accept() picked a free fd before blocking and only locked the write, so
another thread could publish a socket in the same slot. It now picks
and writes the fd in one critical section after Accept() returns. dup()
now re-checks the source fd under the lock.
A duplicated fd shares its socket, so the room packet loop queued each
packet once per fd. Deliver it once per socket.
NIFM: when the selected host adapter is missing, the room still works
and IsNetworkAvailable reports it, but GetCurrentNetworkProfile returned
an empty profile. Report a wired room profile in that case, and put the
room address on the first adapter in EnumerateNetworkInterfaces.
Assisted-by: Claude Opus 5.5 (investigation and implementation)
Diffstat (limited to 'src/core/hle/service/sockets/bsd.h')
| -rw-r--r-- | src/core/hle/service/sockets/bsd.h | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/src/core/hle/service/sockets/bsd.h b/src/core/hle/service/sockets/bsd.h index 0df5c58945..f908edc7d2 100644 --- a/src/core/hle/service/sockets/bsd.h +++ b/src/core/hle/service/sockets/bsd.h @@ -178,11 +178,13 @@ private: s32 FindFreeFileDescriptorHandle() noexcept; bool IsFileDescriptorValid(s32 fd) const noexcept; + /// Copies a descriptor under file_descriptors_mutex; nullopt if fd has no socket + std::optional<FileDescriptor> CopyDescriptor(s32 fd); void BuildErrnoResponse(HLERequestContext& ctx, Errno bsd_errno) const noexcept; static inline std::array<std::optional<FileDescriptor>, MAX_FD> file_descriptors{}; - /// Guards file_descriptors against the room thread, which delivers proxy packets to them + /// Guards file_descriptors. Calls use CopyDescriptor, so sockets outlive a concurrent close. static inline std::mutex file_descriptors_mutex; /// Callback to parse and handle a received wifi packet. |
