diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_io.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_io.cc index f30fbf826..641de8e1e 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_io.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_io.cc @@ -368,8 +368,8 @@ dword_result_t NtRemoveIoCompletion( } uint64_t timeout_ticks = timeout ? static_cast(*timeout) : 0u; - if (port->WaitForNotification(timeout_ticks)) { - auto notification = port->DequeueNotification(); + XIOCompletion::IONotification notification; + if (port->WaitForNotification(timeout_ticks, ¬ification)) { if (key_context) { *key_context = notification.key_context; } diff --git a/src/xenia/kernel/xiocompletion.cc b/src/xenia/kernel/xiocompletion.cc index 4739424ba..0ccc733ed 100644 --- a/src/xenia/kernel/xiocompletion.cc +++ b/src/xenia/kernel/xiocompletion.cc @@ -26,20 +26,17 @@ void XIOCompletion::QueueNotification(IONotification& notification) { notification_semaphore_->Release(1, nullptr); } -XIOCompletion::IONotification XIOCompletion::DequeueNotification() { - std::unique_lock lock(notification_lock_); - assert_false(notifications_.empty()); - - auto notification = notifications_.front(); - notifications_.pop(); - - return notification; -} - -bool XIOCompletion::WaitForNotification(uint64_t wait_ticks) { +bool XIOCompletion::WaitForNotification(uint64_t wait_ticks, + IONotification* notify) { auto ms = std::chrono::milliseconds(TimeoutTicksToMs(wait_ticks)); auto res = threading::Wait(notification_semaphore_.get(), false, ms); if (res == threading::WaitResult::kSuccess) { + std::unique_lock lock(notification_lock_); + assert_false(notifications_.empty()); + + std::memcpy(notify, ¬ifications_.front(), sizeof(IONotification)); + notifications_.pop(); + return true; } diff --git a/src/xenia/kernel/xiocompletion.h b/src/xenia/kernel/xiocompletion.h index 1634f2519..f974ee4ee 100644 --- a/src/xenia/kernel/xiocompletion.h +++ b/src/xenia/kernel/xiocompletion.h @@ -34,11 +34,9 @@ class XIOCompletion : public XObject { }; void QueueNotification(IONotification& notification); - IONotification DequeueNotification(); - // If you call this and it returns true, you MUST dequeue a notification! - // Returns true if the wait was cancelled because a notification was queued. - bool WaitForNotification(uint64_t wait_ticks); + // Returns true if the wait ended because a notification was received. + bool WaitForNotification(uint64_t wait_ticks, IONotification* notify); private: static const uint32_t kMaxNotifications = 1024;