Browse Source
[core/hle/kernel] fix potential datarace where thread may be told to be non-running but inbetween the acquisition of the lock there may be another holder whom puts it on
Signed-off-by: lizzie <lizzie@eden-emu.dev>
lock-term-1
lizzie
2 months ago
No known key found for this signature in database
GPG Key ID: 287378CADCAB13
1 changed files with
13 additions and
9 deletions
src/core/hle/kernel/k_thread.cpp
@ -429,19 +429,23 @@ void KThread::StartTermination() {
}
void KThread : : FinishTermination ( ) {
// Acquire the scheduler lock.
KScopedSchedulerLock lk { m_kernel } ;
// Ensure that the thread is not executing on any core.
if ( m_parent ! = nullptr ) {
for ( std : : size_t i = 0 ; i < static_cast < std : : size_t > ( Core : : Hardware : : NUM_CPU_CORES ) ; + + i ) {
KThread * core_thread { } ;
do {
core_thread = m_kernel . Scheduler ( i ) . GetSchedulerCurrentThread ( ) ;
} while ( core_thread = = this ) ;
bool wait_thread = true ;
lk . unlock ( ) ;
while ( wait_thread ) {
// now "pin" the scheduler so it wont change stuff mid-way
lk . lock ( ) ;
for ( std : : size_t i = 0 ; i < std : : size_t ( Core : : Hardware : : NUM_CPU_CORES ) ; + + i )
is_on_schedule | = m_kernel . Scheduler ( i ) . GetSchedulerCurrentThread ( ) = = this ;
// let scheduler try again
if ( wait_thread )
lk . unlock ( ) ;
}
}
// Acquire the scheduler lock.
KScopedSchedulerLock sl { m_kernel } ;
// Signal.
m_signaled = true ;
KSynchronizationObject : : NotifyAvailable ( ) ;