Prevent AvPlayer movie startup failures across supported hosts (#456)

* Prevent AvPlayer movie startup failures across supported hosts

* Prevent GR2 startup stalls during APR file checks and adaptive mutex self-locks.
This commit is contained in:
StealUrKill
2026-07-20 07:27:37 -05:00
committed by GitHub
parent 3574a3b145
commit 9d187dec55
7 changed files with 493 additions and 25 deletions
@@ -25,6 +25,57 @@ public sealed class PthreadMutexSemanticsTests
Assert.NotEqual(0, KernelPthreadCompatExports.PthreadMutexUnlock(context));
}
[Fact]
public void AdaptiveMutex_GuestTrackedSelfLockReturnsDeadlockAndSingleUnlockReleases()
{
const ulong memoryBase = 0x1_0001_0000;
const ulong mutexAddress = memoryBase + 0x100;
var memory = new AllocatingCpuMemory(memoryBase, 0x4000);
var context = new CpuContext(memory, Generation.Gen5);
Assert.True(context.TryWriteUInt64(mutexAddress, 1)); // Static adaptive initializer.
context[CpuRegister.Rdi] = mutexAddress;
Assert.Equal(0, KernelPthreadCompatExports.PthreadMutexLock(context));
var currentThreadHandle = KernelPthreadState.GetCurrentThreadHandle();
Assert.True(context.TryWriteUInt64(mutexAddress + 8, currentThreadHandle));
Assert.Equal(
(int)OrbisGen2Result.ORBIS_GEN2_ERROR_DEADLOCK,
KernelPthreadCompatExports.PthreadMutexLock(context));
Assert.True(context.TryWriteUInt64(mutexAddress + 8, 0));
Assert.Equal(0, KernelPthreadCompatExports.PthreadMutexUnlock(context));
Assert.Equal(0, KernelPthreadCompatExports.PthreadMutexTrylock(context));
Assert.Equal(0, KernelPthreadCompatExports.PthreadMutexUnlock(context));
}
[Fact]
public void RecursiveMutex_GuestTrackedSelfLockKeepsRecursiveSemantics()
{
const ulong memoryBase = 0x1_0002_0000;
const ulong attrAddress = memoryBase + 0x100;
const ulong mutexAddress = memoryBase + 0x200;
var memory = new AllocatingCpuMemory(memoryBase, 0x4000);
var context = new CpuContext(memory, Generation.Gen5);
context[CpuRegister.Rdi] = attrAddress;
Assert.Equal(0, KernelPthreadCompatExports.PthreadMutexattrInit(context));
context[CpuRegister.Rsi] = 2;
Assert.Equal(0, KernelPthreadCompatExports.PthreadMutexattrSettype(context));
context[CpuRegister.Rdi] = mutexAddress;
context[CpuRegister.Rsi] = attrAddress;
Assert.Equal(0, KernelPthreadCompatExports.PthreadMutexInit(context));
Assert.Equal(0, KernelPthreadCompatExports.PthreadMutexLock(context));
var currentThreadHandle = KernelPthreadState.GetCurrentThreadHandle();
Assert.True(context.TryWriteUInt64(mutexAddress + 8, currentThreadHandle));
Assert.Equal(0, KernelPthreadCompatExports.PthreadMutexLock(context));
Assert.Equal(0, KernelPthreadCompatExports.PthreadMutexUnlock(context));
Assert.Equal(0, KernelPthreadCompatExports.PthreadMutexUnlock(context));
Assert.NotEqual(0, KernelPthreadCompatExports.PthreadMutexUnlock(context));
}
[Fact]
public async Task ContendedMutex_HandsOffOneHostWaiterAtATime()
{