Input: Fixed crash due to multithreading issues w/ controller state access

This commit is contained in:
Sour 2017-12-03 23:12:16 -05:00
parent 2baf1071d4
commit 6588872e42
4 changed files with 20 additions and 3 deletions

View File

@ -30,7 +30,8 @@ protected:
void InitBarcodeStream()
{
string barcodeText(_state.State.begin(), _state.State.end());
vector<uint8_t> state = GetRawState().State;
string barcodeText(state.begin(), state.end());
//Signature at the end, needed for code to be recognized
barcodeText += "EPOCH\xD\xA";

View File

@ -31,6 +31,7 @@ void BaseControlDevice::InternalSetStateFromInput()
void BaseControlDevice::StreamState(bool saving)
{
auto lock = _stateLock.AcquireSafe();
VectorInfo<uint8_t> state{ &_state.State };
Stream(_strobe, state);
}
@ -64,21 +65,25 @@ void BaseControlDevice::StrobeProcessWrite(uint8_t value)
void BaseControlDevice::ClearState()
{
auto lock = _stateLock.AcquireSafe();
_state = ControlDeviceState();
}
ControlDeviceState BaseControlDevice::GetRawState()
{
auto lock = _stateLock.AcquireSafe();
return _state;
}
void BaseControlDevice::SetRawState(ControlDeviceState state)
{
auto lock = _stateLock.AcquireSafe();
_state = state;
}
void BaseControlDevice::SetTextState(string textState)
{
auto lock = _stateLock.AcquireSafe();
ClearState();
if(IsRawString()) {
@ -112,6 +117,7 @@ void BaseControlDevice::SetTextState(string textState)
string BaseControlDevice::GetTextState()
{
auto lock = _stateLock.AcquireSafe();
if(IsRawString()) {
return string((char*)_state.State.data(), _state.State.size());
} else {
@ -133,6 +139,7 @@ string BaseControlDevice::GetTextState()
void BaseControlDevice::EnsureCapacity(int32_t minBitCount)
{
auto lock = _stateLock.AcquireSafe();
uint32_t minByteCount = minBitCount / 8 + 1 + (HasCoordinates() ? 32 : 0);
int32_t gap = minByteCount - (int32_t)_state.State.size();
@ -158,6 +165,7 @@ uint32_t BaseControlDevice::GetByteIndex(uint8_t bit)
bool BaseControlDevice::IsPressed(uint8_t bit)
{
auto lock = _stateLock.AcquireSafe();
EnsureCapacity(bit);
uint8_t bitMask = 1 << (bit % 8);
return (_state.State[GetByteIndex(bit)] & bitMask) != 0;
@ -174,6 +182,7 @@ void BaseControlDevice::SetBitValue(uint8_t bit, bool set)
void BaseControlDevice::SetBit(uint8_t bit)
{
auto lock = _stateLock.AcquireSafe();
EnsureCapacity(bit);
uint8_t bitMask = 1 << (bit % 8);
_state.State[GetByteIndex(bit)] |= bitMask;
@ -181,6 +190,7 @@ void BaseControlDevice::SetBit(uint8_t bit)
void BaseControlDevice::ClearBit(uint8_t bit)
{
auto lock = _stateLock.AcquireSafe();
EnsureCapacity(bit);
uint8_t bitMask = 1 << (bit % 8);
_state.State[GetByteIndex(bit)] &= ~bitMask;
@ -211,6 +221,7 @@ void BaseControlDevice::SetPressedState(uint8_t bit, bool enabled)
void BaseControlDevice::SetCoordinates(MousePosition pos)
{
auto lock = _stateLock.AcquireSafe();
EnsureCapacity(-1);
_state.State[0] = pos.X & 0xFF;
@ -221,6 +232,7 @@ void BaseControlDevice::SetCoordinates(MousePosition pos)
MousePosition BaseControlDevice::GetCoordinates()
{
auto lock = _stateLock.AcquireSafe();
EnsureCapacity(-1);
MousePosition pos;

View File

@ -4,14 +4,18 @@
#include "Snapshotable.h"
#include "ControlManager.h"
#include "ControlDeviceState.h"
#include "../Utilities/SimpleLock.h"
class BaseControlDevice : public Snapshotable
{
protected:
private:
ControlDeviceState _state;
protected:
vector<KeyMapping> _keyMappings;
bool _strobe;
uint8_t _port;
SimpleLock _stateLock;
virtual void RefreshStateBuffer() { }
virtual void StreamState(bool saving);

View File

@ -57,7 +57,7 @@ public:
void OnAfterSetState() override
{
if(_state.State.size() > 0) {
if(GetRawState().State.size() > 0) {
_data = Base64::Decode(GetTextState());
_cycle = CPU::GetCycleCount();
_isPlaying = true;