fix(libkernel): remove a watched descriptor's events before dup2 takes its positioned lock on Windows

dup2 called EqueueDescriptorClosed(to) while holding the positioned-transfer lock of the descriptor, and the in-flight measurement it waits for needs that lock for its sceKernelLseek, so dup2 onto a watched descriptor deadlocked. The events are removed first, before the lock is taken.
This commit is contained in:
MarcZX10 committed 2026-10-27 04:46:00 +00:00
1 parent 9b9f9b4af8
commit ea4eaeae42
1 file changed
+1 -1
+1 -1
View File
@@ -879,13 +879,13 @@ int APS5_VABI dup2_nid_postfix(int from, int to) {
if (from == to) return to;
if (to == 1) PreserveHostStandardOutput();
if (to == 2) PreserveHostStandardError();
EqueueDescriptorClosed(to);
auto positioned = File::LockPositionedTransfer(to);
auto* const standard = HostStandardHandle_nid_no_patch(to);
int duplicated = File::ReplaceSharedMemoryDescriptor_nid_no_patch(from, to);
if (duplicated == -2) duplicated = WithoutParameterHandler([from, to] { return ::_dup2(from, to); });
KeepStandardHandle_nid_no_patch(to, standard);
if (duplicated != 0) return PosixFailure(SceErrorFromErrno(errno) & 0xffff);
EqueueDescriptorClosed(to);
GuestSockets::Forget(to);
File::ForgetDirectoryDescriptor(to);
File::DuplicateDirectoryDescriptor(from, to);