1
0
Fork 0
mirror of https://github.com/Atmosphere-NX/Atmosphere.git synced 2024-12-23 10:52:13 +00:00

libstrat: improve waitable manager cancelsync semantics

This commit is contained in:
Michael Scire 2018-11-07 12:42:06 -08:00
parent 952ee4227d
commit 2894989eb7

View file

@ -60,6 +60,7 @@ class WaitableManager : public SessionManagerBase {
HosMutex process_lock; HosMutex process_lock;
HosMutex signal_lock; HosMutex signal_lock;
HosMutex add_lock; HosMutex add_lock;
HosMutex cur_thread_lock;
bool has_new_waitables = false; bool has_new_waitables = false;
IWaitable *next_signaled = nullptr; IWaitable *next_signaled = nullptr;
@ -97,7 +98,7 @@ class WaitableManager : public SessionManagerBase {
} }
virtual void CancelSynchronization() { virtual void CancelSynchronization() {
svcCancelSynchronization(this->cur_thread_handle); svcCancelSynchronization(GetProcessingThreadHandle());
} }
virtual void NotifySignaled(IWaitable *w) override { virtual void NotifySignaled(IWaitable *w) override {
@ -122,6 +123,16 @@ class WaitableManager : public SessionManagerBase {
ProcessLoop(this); ProcessLoop(this);
} }
private: private:
void SetProcessingThreadHandle(Handle h) {
std::scoped_lock<HosMutex> lk{this->cur_thread_lock};
this->cur_thread_handle = h;
}
Handle GetProcessingThreadHandle() {
std::scoped_lock<HosMutex> lk{this->cur_thread_lock};
return this->cur_thread_handle;
}
static void ProcessLoop(void *t) { static void ProcessLoop(void *t) {
WaitableManager *this_ptr = (WaitableManager *)t; WaitableManager *this_ptr = (WaitableManager *)t;
while (true) { while (true) {
@ -141,17 +152,20 @@ class WaitableManager : public SessionManagerBase {
IWaitable *GetWaitable() { IWaitable *GetWaitable() {
std::scoped_lock lk{this->process_lock}; std::scoped_lock lk{this->process_lock};
/* Set processing thread handle while in scope. */
SetProcessingThreadHandle(GetCurrentThreadHandle());
ON_SCOPE_EXIT {
SetProcessingThreadHandle(INVALID_HANDLE);
};
/* Prepare variables for result. */
this->next_signaled = nullptr; this->next_signaled = nullptr;
IWaitable *result = nullptr; IWaitable *result = nullptr;
/* Add new waitables, if any. */ /* Add new waitables, if any. */
AddWaitablesInternal(); AddWaitablesInternal();
this->cur_thread_handle = GetCurrentThreadHandle();
ON_SCOPE_EXIT {
this->cur_thread_handle = INVALID_HANDLE;
};
/* First, see if anything's already signaled. */ /* First, see if anything's already signaled. */
for (auto &w : this->waitables) { for (auto &w : this->waitables) {
if (w->IsSignaled()) { if (w->IsSignaled()) {