From 7362313611bba22e9f0c349715d83b253e4fc459 Mon Sep 17 00:00:00 2001 From: Garrett Brown Date: Tue, 30 Aug 2016 11:29:44 -0700 Subject: [PATCH] [udev] Protect motor states with a mutex --- src/api/udev/JoystickUdev.cpp | 40 +++++++++++++++++++++++++---------- src/api/udev/JoystickUdev.h | 5 ++++- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/api/udev/JoystickUdev.cpp b/src/api/udev/JoystickUdev.cpp index 28ace248..2ab8887b 100644 --- a/src/api/udev/JoystickUdev.cpp +++ b/src/api/udev/JoystickUdev.cpp @@ -103,10 +103,21 @@ void CJoystickUdev::Deinitialize(void) void CJoystickUdev::ProcessEvents(void) { - uint32_t oldStrength = static_cast(m_previousMotors[MOTOR_STRONG]) + - static_cast(m_previousMotors[MOTOR_WEAK]); - uint32_t newStrength = static_cast(m_motors[MOTOR_STRONG]) + - static_cast(m_motors[MOTOR_WEAK]); + using namespace P8PLATFORM; + + std::array motors; + std::array previousMotors; + + { + CLockObject lock(m_mutex); + motors = m_motors; + previousMotors = m_previousMotors; + } + + uint32_t oldStrength = static_cast(previousMotors[MOTOR_STRONG]) + + static_cast(previousMotors[MOTOR_WEAK]); + uint32_t newStrength = static_cast(motors[MOTOR_STRONG]) + + static_cast(motors[MOTOR_WEAK]); bool bWasPlaying = (oldStrength > 0); bool bIsPlaying = (newStrength > 0); @@ -117,7 +128,7 @@ void CJoystickUdev::ProcessEvents(void) } else if (!bWasPlaying && bIsPlaying) { - UpdateMotorState(); + UpdateMotorState(motors); // Play effect Play(true); @@ -130,10 +141,13 @@ void CJoystickUdev::ProcessEvents(void) else { if (oldStrength != newStrength) - UpdateMotorState(); + UpdateMotorState(motors); } - m_previousMotors = m_motors; + { + CLockObject lock(m_mutex); + m_previousMotors = motors; + } } void CJoystickUdev::Play(bool bPlayStop) @@ -148,7 +162,7 @@ void CJoystickUdev::Play(bool bPlayStop) esyslog("[udev]: Failed to play rumble effect on \"%s\"", Name().c_str()); } -void CJoystickUdev::UpdateMotorState() +void CJoystickUdev::UpdateMotorState(const std::array& motors) { struct ff_effect e = { }; @@ -156,8 +170,8 @@ void CJoystickUdev::UpdateMotorState() e.type = FF_RUMBLE; e.id = old_effect; - e.u.rumble.strong_magnitude = m_motors[MOTOR_STRONG]; - e.u.rumble.weak_magnitude = m_motors[MOTOR_WEAK]; + e.u.rumble.strong_magnitude = motors[MOTOR_STRONG]; + e.u.rumble.weak_magnitude = motors[MOTOR_WEAK]; if (ioctl(m_fd, EVIOCSFF, &e) < 0) { @@ -332,7 +346,9 @@ bool CJoystickUdev::GetProperties() bool CJoystickUdev::SetMotor(unsigned int motorIndex, float magnitude) { - if (!m_bInitialized) + using namespace P8PLATFORM; + + if (!m_bInitialized) return false; if (motorIndex >= MotorCount() || magnitude < 0.0f) @@ -343,6 +359,8 @@ bool CJoystickUdev::SetMotor(unsigned int motorIndex, float magnitude) uint16_t strength = std::min(0xffff, static_cast(magnitude * 0xffff)); + CLockObject lock(m_mutex); + m_motors[motorIndex] = strength; return true; diff --git a/src/api/udev/JoystickUdev.h b/src/api/udev/JoystickUdev.h index 2185303a..ba3b9ac0 100644 --- a/src/api/udev/JoystickUdev.h +++ b/src/api/udev/JoystickUdev.h @@ -41,6 +41,8 @@ #include "api/Joystick.h" +#include "p8-platform/threads/mutex.h" + #include #include #include @@ -74,7 +76,7 @@ namespace JOYSTICK bool SetMotor(unsigned int motorIndex, float magnitude); private: - void UpdateMotorState(); + void UpdateMotorState(const std::array& motors); void Play(bool bPlayStop); struct Axis @@ -100,5 +102,6 @@ namespace JOYSTICK std::map m_axes_bind; // Maps keycodes -> axis and axis info std::array m_motors; std::array m_previousMotors; + P8PLATFORM::CMutex m_mutex; }; }