summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2015-01-17 12:17:36 -0500
committerGravatar bunnei2015-01-21 19:09:09 -0500
commit064be2b86f166d40e0ba61bc4ec0306631b4be9f (patch)
treeee94c2f99c29135af939094c70f966905e3f4bc0 /src
parentWaitSynchronizationN: Implement return values (diff)
downloadyuzu-064be2b86f166d40e0ba61bc4ec0306631b4be9f.tar.gz
yuzu-064be2b86f166d40e0ba61bc4ec0306631b4be9f.tar.xz
yuzu-064be2b86f166d40e0ba61bc4ec0306631b4be9f.zip
WaitSynchronizationN: Handle case where handle_count=0.
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/svc.cpp48
1 files changed, 29 insertions, 19 deletions
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 170ac87f3..f8a5b2548 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -148,27 +148,37 @@ static Result WaitSynchronizationN(s32* out, Handle* handles, s32 handle_count,
148 bool wait_all_succeeded = false; 148 bool wait_all_succeeded = false;
149 int handle_index = 0; 149 int handle_index = 0;
150 150
151 while (handle_index < handle_count) { 151 // If handles were passed in, iterate through them and wait/acquire the objects as needed
152 SharedPtr<Kernel::Object> object = Kernel::g_handle_table.GetGeneric(handles[handle_index]); 152 if (handle_count > 0) {
153 if (object == nullptr) 153 while (handle_index < handle_count) {
154 return InvalidHandle(ErrorModule::Kernel).raw; 154 SharedPtr<Kernel::Object> object = Kernel::g_handle_table.GetGeneric(handles[handle_index]);
155 155 if (object == nullptr)
156 ResultVal<bool> wait = object->WaitSynchronization(handle_index); 156 return InvalidHandle(ErrorModule::Kernel).raw;
157 157
158 wait_thread = (wait.Succeeded() && *wait); 158 ResultVal<bool> wait = object->WaitSynchronization(handle_index);
159
160 wait_thread = (wait.Succeeded() && *wait);
161
162 // If this object waited and we are waiting on all objects to synchronize
163 if (wait_thread && wait_all) {
164 // Enforce later on that this thread does not continue
165 wait_all_succeeded = true;
166 }
167
168 // If this object synchronized and we are not waiting on all objects to synchronize
169 if (!wait_thread && !wait_all)
170 // We're done, the thread will continue
171 break;
159 172
160 // If this object waited and we are waiting on all objects to synchronize 173 handle_index++;
161 if (wait_thread && wait_all) { 174 }
162 // Enforce later on that this thread does not continue 175 }else {
163 wait_all_succeeded = true; 176 // If no handles were passed in, put the thread to sleep only when wait_all=false
177 // NOTE: This is supposed to deadlock if no timeout was specified
178 if (!wait_all) {
179 wait_thread = true;
180 Kernel::WaitCurrentThread(WAITTYPE_SLEEP);
164 } 181 }
165
166 // If this object synchronized and we are not waiting on all objects to synchronize
167 if (!wait_thread && !wait_all)
168 // We're done, the thread will continue
169 break;
170
171 handle_index++;
172 } 182 }
173 183
174 // Change the thread state to waiting if blocking on all handles... 184 // Change the thread state to waiting if blocking on all handles...