소스 검색

kernel/readable_event: Add member function for enforcing a strict reset contract

svcResetSignal relies on the event instance to have already been
signaled before attempting to reset it. If this isn't the case, then an
error code has to be returned.
Lioncash 7 년 전
부모
커밋
a3aa7aaf0b
2개의 변경된 파일22개의 추가작업 그리고 1개의 파일을 삭제
  1. 11 1
      src/core/hle/kernel/readable_event.cpp
  2. 11 0
      src/core/hle/kernel/readable_event.h

+ 11 - 1
src/core/hle/kernel/readable_event.cpp

@@ -4,10 +4,10 @@
 
 #include <algorithm>
 #include "common/assert.h"
+#include "core/hle/kernel/errors.h"
 #include "core/hle/kernel/object.h"
 #include "core/hle/kernel/readable_event.h"
 #include "core/hle/kernel/thread.h"
-#include "core/hle/kernel/writable_event.h"
 
 namespace Kernel {
 
@@ -34,6 +34,16 @@ void ReadableEvent::Clear() {
     signaled = false;
 }
 
+ResultCode ReadableEvent::Reset() {
+    if (!signaled) {
+        return ERR_INVALID_STATE;
+    }
+
+    Clear();
+
+    return RESULT_SUCCESS;
+}
+
 void ReadableEvent::WakeupAllWaitingThreads() {
     WaitObject::WakeupAllWaitingThreads();
 

+ 11 - 0
src/core/hle/kernel/readable_event.h

@@ -7,6 +7,8 @@
 #include "core/hle/kernel/object.h"
 #include "core/hle/kernel/wait_object.h"
 
+union ResultCode;
+
 namespace Kernel {
 
 class KernelCore;
@@ -39,8 +41,17 @@ public:
 
     void WakeupAllWaitingThreads() override;
 
+    /// Unconditionally clears the readable event's state.
     void Clear();
 
+    /// Clears the readable event's state if and only if it
+    /// has already been signaled.
+    ///
+    /// @pre The event must be in a signaled state. If this event
+    ///      is in an unsignaled state and this function is called,
+    ///      then ERR_INVALID_STATE will be returned.
+    ResultCode Reset();
+
 private:
     explicit ReadableEvent(KernelCore& kernel);