From b2e8e69ebc3f687857e6ab146a13f3e11cde135c Mon Sep 17 00:00:00 2001 From: N0r1x <1norixion1@gmail.com> Date: Sat, 30 Jul 2016 15:27:20 +0200 Subject: [PATCH] Changed classes marked with race conditions in emu_window files --- src/common/emu_window.cpp | 16 +++++++++++---- src/common/emu_window.h | 41 +++++++++++++++++++++------------------ 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/src/common/emu_window.cpp b/src/common/emu_window.cpp index fd728c109..b6d4ff4bc 100644 --- a/src/common/emu_window.cpp +++ b/src/common/emu_window.cpp @@ -12,11 +12,15 @@ #include "video_core/video_core.h" void EmuWindow::ButtonPressed(Service::HID::PadState pad) { - pad_state.hex |= pad.hex; + Service::HID::PadState temp=pad_state.load(); + temp.hex |= pad.hex; + pad_state.store(temp); } void EmuWindow::ButtonReleased(Service::HID::PadState pad) { - pad_state.hex &= ~pad.hex; + Service::HID::PadState temp=pad_state.load(); + temp.hex &= ~pad.hex; + pad_state.store(temp); } void EmuWindow::CirclePadUpdated(float x, float y) { @@ -70,14 +74,18 @@ void EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y) { (framebuffer_layout.bottom_screen.bottom - framebuffer_layout.bottom_screen.top); touch_pressed = true; - pad_state.touch.Assign(1); + Service::HID::PadState temp=pad_state.load(); + temp.touch.Assign(1); + pad_state.store(temp); } void EmuWindow::TouchReleased() { touch_pressed = false; touch_x = 0; touch_y = 0; - pad_state.touch.Assign(0); + Service::HID::PadState temp=pad_state.load(); + temp.touch.Assign(0); + pad_state.store(temp); } void EmuWindow::TouchMoved(unsigned framebuffer_x, unsigned framebuffer_y) { diff --git a/src/common/emu_window.h b/src/common/emu_window.h index 57e303b6d..2629fb4bd 100644 --- a/src/common/emu_window.h +++ b/src/common/emu_window.h @@ -11,6 +11,7 @@ #include "common/math_util.h" #include "core/hle/service/hid/hid.h" +#include /** * Abstraction class used to provide an interface between emulation code and the frontend @@ -115,32 +116,32 @@ public: * Gets the current pad state (which buttons are pressed). * @note This should be called by the core emu thread to get a state set by the window thread. * @note This doesn't include analog input like circle pad direction - * @todo Fix this function to be thread-safe. + * @todo Confirm the update from PadState to atomic doesn't cause any problems * @return PadState object indicating the current pad state */ Service::HID::PadState GetPadState() const { - return pad_state; + return pad_state.load(); } /** * Gets the current circle pad state. * @note This should be called by the core emu thread to get a state set by the window thread. - * @todo Fix this function to be thread-safe. + * @todo Confirm the update from s16 to atomic doesn't cause any problems * @return std::tuple of (x, y), where `x` and `y` are the circle pad coordinates */ std::tuple GetCirclePadState() const { - return std::make_tuple(circle_pad_x, circle_pad_y); + return std::make_tuple(circle_pad_x.load(), circle_pad_y.load()); } /** * Gets the current touch screen state (touch X/Y coordinates and whether or not it is pressed). * @note This should be called by the core emu thread to get a state set by the window thread. - * @todo Fix this function to be thread-safe. + * @todo Confirm the update from u16/bool to atomic doesn't cause any problems * @return std::tuple of (x, y, pressed) where `x` and `y` are the touch coordinates and * `pressed` is true if the touch screen is currently being pressed */ - std::tuple GetTouchState() const { - return std::make_tuple(touch_x, touch_y, touch_pressed); + std::tuple< u16,u16,bool> GetTouchState() const { + return std::make_tuple(touch_x.load(), touch_y.load(), touch_pressed.load()); } /** @@ -220,12 +221,14 @@ protected: // TODO: Find a better place to set this. config.min_client_area_size = std::make_pair(400u, 480u); active_config = config; - pad_state.hex = 0; - touch_x = 0; - touch_y = 0; - circle_pad_x = 0; - circle_pad_y = 0; - touch_pressed = false; + Service::HID::PadState temp; + temp.hex = 0; + pad_state.store(temp); + touch_x ={0}; + touch_y ={0}; + circle_pad_x = {0}; + circle_pad_y = {0}; + touch_pressed = {false}; } virtual ~EmuWindow() {} @@ -280,18 +283,18 @@ private: WindowConfig config; ///< Internal configuration (changes pending for being applied in ProcessConfigurationChanges) WindowConfig active_config; ///< Internal active configuration - bool touch_pressed; ///< True if touchpad area is currently pressed, otherwise false + std::atomic touch_pressed; ///< True if touchpad area is currently pressed, otherwise false - u16 touch_x; ///< Touchpad X-position in native 3DS pixel coordinates (0-320) - u16 touch_y; ///< Touchpad Y-position in native 3DS pixel coordinates (0-240) + std::atomic touch_x; ///< Touchpad X-position in native 3DS pixel coordinates (0-320) + std::atomic touch_y; ///< Touchpad Y-position in native 3DS pixel coordinates (0-240) - s16 circle_pad_x; ///< Circle pad X-position in native 3DS pixel coordinates (-156 - 156) - s16 circle_pad_y; ///< Circle pad Y-position in native 3DS pixel coordinates (-156 - 156) + std::atomic circle_pad_x; ///< Circle pad X-position in native 3DS pixel coordinates (-156 - 156) + std::atomic circle_pad_y; ///< Circle pad Y-position in native 3DS pixel coordinates (-156 - 156) /** * Clip the provided coordinates to be inside the touchscreen area. */ std::tuple ClipToTouchScreen(unsigned new_x, unsigned new_y); - Service::HID::PadState pad_state; + std::atomic pad_state; };