diff options
| author | 2015-01-17 12:17:36 -0500 | |
|---|---|---|
| committer | 2015-01-21 19:09:09 -0500 | |
| commit | 064be2b86f166d40e0ba61bc4ec0306631b4be9f (patch) | |
| tree | ee94c2f99c29135af939094c70f966905e3f4bc0 /src | |
| parent | WaitSynchronizationN: Implement return values (diff) | |
| download | yuzu-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.cpp | 48 |
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... |