summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/hle/kernel/hle_ipc.cpp19
-rw-r--r--src/core/hle/kernel/svc.cpp5
-rw-r--r--src/core/hle/kernel/synchronization.cpp1
-rw-r--r--src/core/hle/kernel/thread.cpp35
-rw-r--r--src/core/hle/kernel/thread.h16
5 files changed, 39 insertions, 37 deletions
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp
index 955d5fe1c..e74d91670 100644
--- a/src/core/hle/kernel/hle_ipc.cpp
+++ b/src/core/hle/kernel/hle_ipc.cpp
@@ -21,8 +21,8 @@
#include "core/hle/kernel/object.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/readable_event.h"
-#include "core/hle/kernel/server_session.h"
#include "core/hle/kernel/scheduler.h"
+#include "core/hle/kernel/server_session.h"
#include "core/hle/kernel/thread.h"
#include "core/hle/kernel/time_manager.h"
#include "core/hle/kernel/writable_event.h"
@@ -49,14 +49,6 @@ std::shared_ptr<WritableEvent> HLERequestContext::SleepClientThread(
const std::string& reason, u64 timeout, WakeupCallback&& callback,
std::shared_ptr<WritableEvent> writable_event) {
// Put the client thread to sleep until the wait event is signaled or the timeout expires.
- thread->SetHLECallback(
- [context = *this, callback](ThreadWakeupReason reason, std::shared_ptr<Thread> thread,
- std::shared_ptr<SynchronizationObject> object,
- std::size_t index) mutable -> bool {
- callback(thread, context, reason);
- context.WriteToOutgoingCommandBuffer(*thread);
- return true;
- });
if (!writable_event) {
// Create event if not provided
@@ -67,6 +59,15 @@ std::shared_ptr<WritableEvent> HLERequestContext::SleepClientThread(
{
Handle event_handle = InvalidHandle;
SchedulerLockAndSleep lock(kernel, event_handle, thread.get(), timeout);
+ thread->SetHLECallback(
+ [context = *this, callback](std::shared_ptr<Thread> thread) mutable -> bool {
+ ThreadWakeupReason reason = thread->GetSignalingResult() == RESULT_TIMEOUT
+ ? ThreadWakeupReason::Timeout
+ : ThreadWakeupReason::Signal;
+ callback(thread, context, reason);
+ context.WriteToOutgoingCommandBuffer(*thread);
+ return true;
+ });
const auto readable_event{writable_event->GetReadableEvent()};
writable_event->Clear();
thread->SetStatus(ThreadStatus::WaitHLEEvent);
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 4c1040a3b..9f46a1758 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -333,17 +333,16 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) {
thread->SetStatus(ThreadStatus::WaitIPC);
session->SendSyncRequest(SharedFrom(thread), system.Memory());
}
- ResultCode result = thread->GetSignalingResult();
if (thread->HasHLECallback()) {
Handle event_handle = thread->GetHLETimeEvent();
if (event_handle != InvalidHandle) {
auto& time_manager = system.Kernel().TimeManager();
time_manager.UnscheduleTimeEvent(event_handle);
}
- thread->InvokeHLECallback(ThreadWakeupReason::Timeout, SharedFrom(thread), nullptr, 0);
+ thread->InvokeHLECallback(SharedFrom(thread));
}
- return result;
+ return RESULT_SUCCESS;
}
static ResultCode SendSyncRequest32(Core::System& system, Handle handle) {
diff --git a/src/core/hle/kernel/synchronization.cpp b/src/core/hle/kernel/synchronization.cpp
index c60c5bb42..4ee7ad93c 100644
--- a/src/core/hle/kernel/synchronization.cpp
+++ b/src/core/hle/kernel/synchronization.cpp
@@ -28,6 +28,7 @@ void Synchronization::SignalObject(SynchronizationObject& obj) const {
time_manager.CancelTimeEvent(thread.get());
}
}
+ obj.ClearWaitingThreads();
}
}
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index a645ee3a2..16babe71a 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -47,19 +47,21 @@ Thread::Thread(KernelCore& kernel) : SynchronizationObject{kernel} {}
Thread::~Thread() = default;
void Thread::Stop() {
- SchedulerLock lock(kernel);
- // Cancel any outstanding wakeup events for this thread
- Signal();
- Core::System::GetInstance().CoreTiming().UnscheduleEvent(kernel.ThreadWakeupCallbackEventType(),
- global_handle);
- kernel.GlobalHandleTable().Close(global_handle);
- global_handle = 0;
- SetStatus(ThreadStatus::Dead);
+ {
+ SchedulerLock lock(kernel);
+ // Cancel any outstanding wakeup events for this thread
+ Signal();
+ Core::System::GetInstance().CoreTiming().UnscheduleEvent(
+ kernel.ThreadWakeupCallbackEventType(), global_handle);
+ kernel.GlobalHandleTable().Close(global_handle);
+ SetStatus(ThreadStatus::Dead);
- owner_process->UnregisterThread(this);
+ owner_process->UnregisterThread(this);
- // Mark the TLS slot in the thread's page as free.
- owner_process->FreeTLSRegion(tls_address);
+ // Mark the TLS slot in the thread's page as free.
+ owner_process->FreeTLSRegion(tls_address);
+ }
+ global_handle = 0;
}
void Thread::WakeAfterDelay(s64 nanoseconds) {
@@ -112,8 +114,6 @@ void Thread::ResumeFromWait() {
return;
}
- hle_callback = nullptr;
-
if (activity == ThreadActivity::Paused) {
SetStatus(ThreadStatus::Paused);
return;
@@ -398,14 +398,13 @@ bool Thread::AllSynchronizationObjectsReady() const {
bool Thread::InvokeWakeupCallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread,
std::shared_ptr<SynchronizationObject> object,
std::size_t index) {
- ASSERT(hle_callback);
- return hle_callback(reason, std::move(thread), std::move(object), index);
+ ASSERT(wakeup_callback);
+ return wakeup_callback(reason, std::move(thread), std::move(object), index);
}
-bool Thread::InvokeHLECallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread,
- std::shared_ptr<SynchronizationObject> object, std::size_t index) {
+bool Thread::InvokeHLECallback(std::shared_ptr<Thread> thread) {
ASSERT(hle_callback);
- return hle_callback(reason, std::move(thread), std::move(object), index);
+ return hle_callback(std::move(thread));
}
void Thread::SetActivity(ThreadActivity value) {
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 04496f96e..c4c9d69ec 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -448,7 +448,7 @@ public:
}
bool HasWakeupCallback() const {
- return hle_callback != nullptr;
+ return wakeup_callback != nullptr;
}
bool HasHLECallback() const {
@@ -456,10 +456,10 @@ public:
}
void SetWakeupCallback(WakeupCallback callback) {
- hle_callback = std::move(callback);
+ wakeup_callback = std::move(callback);
}
- void SetHLECallback(WakeupCallback callback) {
+ void SetHLECallback(HLECallback callback) {
hle_callback = std::move(callback);
}
@@ -487,8 +487,7 @@ public:
*/
bool InvokeWakeupCallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread,
std::shared_ptr<SynchronizationObject> object, std::size_t index);
- bool InvokeHLECallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread,
- std::shared_ptr<SynchronizationObject> object, std::size_t index);
+ bool InvokeHLECallback(std::shared_ptr<Thread> thread);
u32 GetIdealCore() const {
return ideal_core;
@@ -622,8 +621,11 @@ private:
/// Callback that will be invoked when the thread is resumed from a waiting state. If the thread
/// was waiting via WaitSynchronization then the object will be the last object that became
- /// available. In case of a timeout, the object will be nullptr.
- WakeupCallback hle_callback;
+ /// available. In case of a timeout, the object will be nullptr. DEPRECATED
+ WakeupCallback wakeup_callback;
+
+ /// Callback for HLE Events
+ HLECallback hle_callback;
Handle hle_time_event;
Scheduler* scheduler = nullptr;