diff options
Diffstat (limited to 'src/core/hle/kernel/thread.cpp')
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 61378211f..690cb20b3 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -247,12 +247,15 @@ static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) { | |||
| 247 | 247 | ||
| 248 | if (thread->status == THREADSTATUS_WAIT_SYNCH_ANY || | 248 | if (thread->status == THREADSTATUS_WAIT_SYNCH_ANY || |
| 249 | thread->status == THREADSTATUS_WAIT_SYNCH_ALL || thread->status == THREADSTATUS_WAIT_ARB) { | 249 | thread->status == THREADSTATUS_WAIT_SYNCH_ALL || thread->status == THREADSTATUS_WAIT_ARB) { |
| 250 | thread->wait_set_output = false; | 250 | |
| 251 | // Invoke the wakeup callback before clearing the wait objects | ||
| 252 | if (thread->wakeup_callback) | ||
| 253 | thread->wakeup_callback(ThreadWakeupReason::Timeout, thread, nullptr); | ||
| 254 | |||
| 251 | // Remove the thread from each of its waiting objects' waitlists | 255 | // Remove the thread from each of its waiting objects' waitlists |
| 252 | for (auto& object : thread->wait_objects) | 256 | for (auto& object : thread->wait_objects) |
| 253 | object->RemoveWaitingThread(thread.get()); | 257 | object->RemoveWaitingThread(thread.get()); |
| 254 | thread->wait_objects.clear(); | 258 | thread->wait_objects.clear(); |
| 255 | thread->SetWaitSynchronizationResult(RESULT_TIMEOUT); | ||
| 256 | } | 259 | } |
| 257 | 260 | ||
| 258 | thread->ResumeFromWait(); | 261 | thread->ResumeFromWait(); |
| @@ -278,6 +281,9 @@ void Thread::ResumeFromWait() { | |||
| 278 | break; | 281 | break; |
| 279 | 282 | ||
| 280 | case THREADSTATUS_READY: | 283 | case THREADSTATUS_READY: |
| 284 | // The thread's wakeup callback must have already been cleared when the thread was first | ||
| 285 | // awoken. | ||
| 286 | ASSERT(wakeup_callback == nullptr); | ||
| 281 | // If the thread is waiting on multiple wait objects, it might be awoken more than once | 287 | // If the thread is waiting on multiple wait objects, it might be awoken more than once |
| 282 | // before actually resuming. We can ignore subsequent wakeups if the thread status has | 288 | // before actually resuming. We can ignore subsequent wakeups if the thread status has |
| 283 | // already been set to THREADSTATUS_READY. | 289 | // already been set to THREADSTATUS_READY. |
| @@ -293,6 +299,8 @@ void Thread::ResumeFromWait() { | |||
| 293 | return; | 299 | return; |
| 294 | } | 300 | } |
| 295 | 301 | ||
| 302 | wakeup_callback = nullptr; | ||
| 303 | |||
| 296 | ready_queue.push_back(current_priority, this); | 304 | ready_queue.push_back(current_priority, this); |
| 297 | status = THREADSTATUS_READY; | 305 | status = THREADSTATUS_READY; |
| 298 | Core::System::GetInstance().PrepareReschedule(); | 306 | Core::System::GetInstance().PrepareReschedule(); |
| @@ -394,7 +402,6 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, | |||
| 394 | thread->nominal_priority = thread->current_priority = priority; | 402 | thread->nominal_priority = thread->current_priority = priority; |
| 395 | thread->last_running_ticks = CoreTiming::GetTicks(); | 403 | thread->last_running_ticks = CoreTiming::GetTicks(); |
| 396 | thread->processor_id = processor_id; | 404 | thread->processor_id = processor_id; |
| 397 | thread->wait_set_output = false; | ||
| 398 | thread->wait_objects.clear(); | 405 | thread->wait_objects.clear(); |
| 399 | thread->wait_address = 0; | 406 | thread->wait_address = 0; |
| 400 | thread->name = std::move(name); | 407 | thread->name = std::move(name); |