Check that the mutex address matches before waking a waiting thread

This commit is contained in:
gdkchan 2018-04-21 14:15:36 -03:00
commit babfcde885

View file

@ -187,31 +187,41 @@ namespace Ryujinx.Core.OsHle.Kernel
return false; return false;
} }
KThread OwnerThread = CurrThread.NextMutexThread; lock (CurrThread)
CurrThread.NextMutexThread = null;
if (OwnerThread != null)
{ {
int HasListeners = OwnerThread.NextMutexThread != null ? MutexHasListenersMask : 0; //This is the new thread that will not own the mutex.
//If no threads are waiting for the lock, then it should be null.
KThread OwnerThread = CurrThread.NextMutexThread;
Process.Memory.WriteInt32(MutexAddress, HasListeners | OwnerThread.WaitHandle); while (OwnerThread?.NextMutexThread != null && OwnerThread.MutexAddress != MutexAddress)
{
OwnerThread = OwnerThread.NextMutexThread;
}
OwnerThread.WaitHandle = 0; CurrThread.NextMutexThread = null;
OwnerThread.MutexAddress = 0;
OwnerThread.CondVarAddress = 0;
OwnerThread.ResetPriority(); if (OwnerThread != null)
{
int HasListeners = OwnerThread.NextMutexThread != null ? MutexHasListenersMask : 0;
Process.Scheduler.WakeUp(OwnerThread); Process.Memory.WriteInt32(MutexAddress, HasListeners | OwnerThread.WaitHandle);
return true; OwnerThread.WaitHandle = 0;
} OwnerThread.MutexAddress = 0;
else OwnerThread.CondVarAddress = 0;
{
Process.Memory.WriteInt32(MutexAddress, 0);
return false; OwnerThread.ResetPriority();
Process.Scheduler.WakeUp(OwnerThread);
return true;
}
else
{
Process.Memory.WriteInt32(MutexAddress, 0);
return false;
}
} }
} }
@ -246,6 +256,8 @@ namespace Ryujinx.Core.OsHle.Kernel
DoInsert &= CurrThread != WaitThread; DoInsert &= CurrThread != WaitThread;
} }
//Only insert if the node doesn't already exist in the list.
//This prevents circular references.
if (DoInsert) if (DoInsert)
{ {
if (WaitThread.NextCondVarThread != null) if (WaitThread.NextCondVarThread != null)