Guard Event.hxx against races.

This commit is contained in:
Christian Speckner 2018-09-19 22:05:59 +02:00
parent 0715b691a0
commit 6d0614ef35
35 changed files with 94 additions and 60 deletions

View File

@ -54,7 +54,7 @@ KeyboardWidget::KeyboardWidget(GuiObject* boss, const GUI::Font& font,
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void KeyboardWidget::loadConfig()
{
const Event& event = instance().eventHandler().event();
Event& event = instance().eventHandler().event();
for(int i = 0; i < 12; ++i)
myBox[i]->setState(event.get(myEvent[i]));
}

View File

@ -30,7 +30,7 @@ class AmigaMouse : public PointingDevice
@param event The event object to use for events
@param system The system using this controller
*/
AmigaMouse(Jack jack, const Event& event, const System& system)
AmigaMouse(Jack jack, Event& event, const System& system)
: PointingDevice(jack, event, system, Controller::AmigaMouse,
trackballSensitivity) { }
virtual ~AmigaMouse() = default;

View File

@ -30,7 +30,7 @@ class AtariMouse : public PointingDevice
@param event The event object to use for events
@param system The system using this controller
*/
AtariMouse(Jack jack, const Event& event, const System& system)
AtariMouse(Jack jack, Event& event, const System& system)
: PointingDevice(jack, event, system, Controller::AtariMouse,
trackballSensitivity) { }
virtual ~AtariMouse() = default;

View File

@ -20,7 +20,7 @@
#include "AtariVox.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
AtariVox::AtariVox(Jack jack, const Event& event, const System& system,
AtariVox::AtariVox(Jack jack, Event& event, const System& system,
const SerialPort& port, const string& portname,
const string& eepromfile)
: SaveKey(jack, event, system, eepromfile, Controller::AtariVox),

View File

@ -45,7 +45,7 @@ class AtariVox : public SaveKey
@param portname Name of the port used for reading and writing
@param eepromfile The file containing the EEPROM data
*/
AtariVox(Jack jack, const Event& event, const System& system,
AtariVox(Jack jack, Event& event, const System& system,
const SerialPort& port, const string& portname,
const string& eepromfile);
virtual ~AtariVox() = default;

View File

@ -19,7 +19,7 @@
#include "Booster.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BoosterGrip::BoosterGrip(Jack jack, const Event& event, const System& system)
BoosterGrip::BoosterGrip(Jack jack, Event& event, const System& system)
: Controller(jack, event, system, Controller::BoosterGrip),
myControlID(-1)
{

View File

@ -38,7 +38,7 @@ class BoosterGrip : public Controller
@param event The event object to use for events
@param system The system using this controller
*/
BoosterGrip(Jack jack, const Event& event, const System& system);
BoosterGrip(Jack jack, Event& event, const System& system);
virtual ~BoosterGrip() = default;
public:

View File

@ -20,12 +20,11 @@
#include "CompuMate.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CompuMate::CompuMate(const Console& console, const Event& event,
CompuMate::CompuMate(const Console& console, Event& event,
const System& system)
: myConsole(console),
myEvent(event),
myColumn(0),
myKeyTable(nullptr)
myKeyTable(event.getKeys())
{
// These controller pointers will be retrieved by the Console, which will
// also take ownership of them
@ -43,15 +42,7 @@ CompuMate::CompuMate(const Console& console, const Event& event,
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CompuMate::enableKeyHandling(bool enable)
{
if(enable)
myKeyTable = myEvent.getKeys();
else
{
for(uInt32 i = 0; i < KBDK_LAST; ++i)
myInternalKeyTable[i] = false;
myKeyTable = myInternalKeyTable;
}
myKeyTable.enable(enable);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -50,7 +50,7 @@ class CompuMate
@param event The event object to use for events
@param system The system using this controller
*/
CompuMate(const Console& console, const Event& event, const System& system);
CompuMate(const Console& console, Event& event, const System& system);
virtual ~CompuMate() = default; // Controllers are deleted outside this class
/**
@ -98,7 +98,7 @@ class CompuMate
@param event The event object to use for events
@param system The system using this controller
*/
CMControl(class CompuMate& handler, Controller::Jack jack, const Event& event,
CMControl(class CompuMate& handler, Controller::Jack jack, Event& event,
const System& system)
: Controller(jack, event, system, Controller::CompuMate),
myHandler(handler) { }
@ -134,7 +134,6 @@ class CompuMate
private:
// Console and Event objects
const Console& myConsole;
const Event& myEvent;
// Left and right controllers
unique_ptr<Controller> myLeftController, myRightController;
@ -143,11 +142,7 @@ class CompuMate
uInt8 myColumn;
// The keyboard state array (tells us the current state of the keyboard)
const bool* myKeyTable;
// Array of keyboard key states when in the debugger (the normal keyboard
// keys are ignored in such a case)
bool myInternalKeyTable[KBDK_LAST];
Event::KeyTable myKeyTable;
private:
// Following constructors and assignment operators not supported

View File

@ -372,7 +372,7 @@ class Console : public Serializable
OSystem& myOSystem;
// Reference to the event object to use
const Event& myEvent;
Event& myEvent;
// Properties for the game
Properties myProperties;

View File

@ -21,7 +21,7 @@
#include "Control.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Controller::Controller(Jack jack, const Event& event, const System& system,
Controller::Controller(Jack jack, Event& event, const System& system,
Type type)
: myJack(jack),
myEvent(event),

View File

@ -108,7 +108,7 @@ class Controller : public Serializable
@param system The system using this controller
@param type The type for this controller
*/
Controller(Jack jack, const Event& event, const System& system,
Controller(Jack jack, Event& event, const System& system,
Type type);
virtual ~Controller() = default;
@ -275,7 +275,7 @@ class Controller : public Serializable
const Jack myJack;
/// Reference to the event object this controller uses
const Event& myEvent;
Event& myEvent;
/// Pointer to the System object (used for timing purposes)
const System& mySystem;

View File

@ -21,7 +21,7 @@
#include "Driving.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Driving::Driving(Jack jack, const Event& event, const System& system)
Driving::Driving(Jack jack, Event& event, const System& system)
: Controller(jack, event, system, Controller::Driving),
myCounter(0),
myGrayIndex(0),

View File

@ -37,7 +37,7 @@ class Driving : public Controller
@param event The event object to use for events
@param system The system using this controller
*/
Driving(Jack jack, const Event& event, const System& system);
Driving(Jack jack, Event& event, const System& system);
virtual ~Driving() = default;
public:

View File

@ -18,6 +18,8 @@
#ifndef EVENT_HXX
#define EVENT_HXX
#include <mutex>
#include "bspf.hxx"
#include "StellaKeys.hxx"
@ -80,6 +82,36 @@ class Event
LastType
};
class KeyTable {
public:
KeyTable(const bool* keyTable, std::mutex& mutex)
: myKeyTable(keyTable),
myMutex(mutex),
myIsEnabled(true)
{}
bool operator[](int type) {
if (!myIsEnabled) return false;
std::lock_guard<std::mutex> lock(myMutex);
return myKeyTable[type];
}
void enable(bool isEnabled) {
myIsEnabled = isEnabled;
}
private:
const bool *myKeyTable;
std::mutex& myMutex;
bool myIsEnabled;
};
public:
/**
Create a new event object.
@ -90,18 +122,28 @@ class Event
/**
Get the value associated with the event of the specified type.
*/
Int32 get(Type type) const { return myValues[type]; }
Int32 get(Type type) {
std::lock_guard<std::mutex> lock(myMutex);
return myValues[type];
}
/**
Set the value associated with the event of the specified type.
*/
void set(Type type, Int32 value) { myValues[type] = value; }
void set(Type type, Int32 value) {
std::lock_guard<std::mutex> lock(myMutex);
myValues[type] = value;
}
/**
Clears the event array (resets to initial state).
*/
void clear()
{
std::lock_guard<std::mutex> lock(myMutex);
for(uInt32 i = 0; i < LastType; ++i)
myValues[i] = Event::NoType;
@ -112,12 +154,16 @@ class Event
/**
Get the keytable associated with this event.
*/
const bool* getKeys() const { return myKeyTable; }
KeyTable getKeys() { return KeyTable(myKeyTable, myMutex); }
/**
Set the value associated with the event of the specified type.
*/
void setKey(StellaKey key, bool state) { myKeyTable[key] = state; }
void setKey(StellaKey key, bool state) {
std::lock_guard<std::mutex> lock(myMutex);
myKeyTable[key] = state;
}
/**
Tests if a given event represents continuous or analog values.
@ -143,6 +189,8 @@ class Event
// Array of keyboard key states
bool myKeyTable[KBDK_LAST];
std::mutex myMutex;
private:
// Following constructors and assignment operators not supported
Event(const Event&) = delete;

View File

@ -63,7 +63,7 @@ class EventHandler
@return The event object
*/
const Event& event() const { return myEvent; }
Event& event() { return myEvent; }
/**
Initialize state of this eventhandler.

View File

@ -19,7 +19,7 @@
#include "Genesis.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Genesis::Genesis(Jack jack, const Event& event, const System& system)
Genesis::Genesis(Jack jack, Event& event, const System& system)
: Controller(jack, event, system, Controller::Genesis),
myControlID(-1)
{

View File

@ -40,7 +40,7 @@ class Genesis : public Controller
@param event The event object to use for events
@param system The system using this controller
*/
Genesis(Jack jack, const Event& event, const System& system);
Genesis(Jack jack, Event& event, const System& system);
virtual ~Genesis() = default;
public:

View File

@ -19,7 +19,7 @@
#include "Joystick.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Joystick::Joystick(Jack jack, const Event& event, const System& system)
Joystick::Joystick(Jack jack, Event& event, const System& system)
: Controller(jack, event, system, Controller::Joystick),
myControlID(-1)
{

View File

@ -37,7 +37,7 @@ class Joystick : public Controller
@param event The event object to use for events
@param system The system using this controller
*/
Joystick(Jack jack, const Event& event, const System& system);
Joystick(Jack jack, Event& event, const System& system);
virtual ~Joystick() = default;
public:

View File

@ -19,7 +19,7 @@
#include "Keyboard.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Keyboard::Keyboard(Jack jack, const Event& event, const System& system)
Keyboard::Keyboard(Jack jack, Event& event, const System& system)
: Controller(jack, event, system, Controller::Keyboard)
{
if(myJack == Left)

View File

@ -37,7 +37,7 @@ class Keyboard : public Controller
@param event The event object to use for events
@param system The system using this controller
*/
Keyboard(Jack jack, const Event& event, const System& system);
Keyboard(Jack jack, Event& event, const System& system);
virtual ~Keyboard() = default;
public:

View File

@ -21,7 +21,7 @@
#include "KidVid.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
KidVid::KidVid(Jack jack, const Event& event, const System& system,
KidVid::KidVid(Jack jack, Event& event, const System& system,
const string& rommd5)
: Controller(jack, event, system, Controller::KidVid),
myEnabled(myJack == Right),

View File

@ -47,7 +47,7 @@ class KidVid : public Controller
@param system The system using this controller
@param md5sum The md5 of the ROM using this controller
*/
KidVid(Jack jack, const Event& event, const System& system,
KidVid(Jack jack, Event& event, const System& system,
const string& md5sum);
virtual ~KidVid();

View File

@ -19,7 +19,7 @@
#include "MindLink.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MindLink::MindLink(Jack jack, const Event& event, const System& system)
MindLink::MindLink(Jack jack, Event& event, const System& system)
: Controller(jack, event, system, Controller::MindLink),
myMindlinkPos(0x2800),
myMindlinkShift(1),

View File

@ -47,7 +47,7 @@ class MindLink : public Controller
@param event The event object to use for events
@param system The system using this controller
*/
MindLink(Jack jack, const Event& event, const System& system);
MindLink(Jack jack, Event& event, const System& system);
virtual ~MindLink() = default;
public:

View File

@ -19,7 +19,7 @@
#include "Paddles.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Paddles::Paddles(Jack jack, const Event& event, const System& system,
Paddles::Paddles(Jack jack, Event& event, const System& system,
bool swappaddle, bool swapaxis, bool swapdir)
: Controller(jack, event, system, Controller::Paddles),
myMPaddleID(-1),

View File

@ -43,7 +43,7 @@ class Paddles : public Controller
causes movement (lesser axis values cause paddle
resistance to decrease instead of increase)
*/
Paddles(Jack jack, const Event& event, const System& system,
Paddles(Jack jack, Event& event, const System& system,
bool swappaddle, bool swapaxis, bool swapdir);
virtual ~Paddles() = default;

View File

@ -23,7 +23,7 @@
#include "PointingDevice.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PointingDevice::PointingDevice(Jack jack, const Event& event,
PointingDevice::PointingDevice(Jack jack, Event& event,
const System& system, Controller::Type type,
float sensitivity)
: Controller(jack, event, system, type),

View File

@ -35,7 +35,7 @@ class PointingDevice : public Controller
friend class PointingDeviceWidget;
public:
PointingDevice(Jack jack, const Event& event,
PointingDevice(Jack jack, Event& event,
const System& system, Controller::Type type,
float sensitivity);
virtual ~PointingDevice() = default;

View File

@ -20,7 +20,7 @@
#include "SaveKey.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SaveKey::SaveKey(Jack jack, const Event& event, const System& system,
SaveKey::SaveKey(Jack jack, Event& event, const System& system,
const string& eepromfile, Type type)
: Controller(jack, event, system, type)
{
@ -30,7 +30,7 @@ SaveKey::SaveKey(Jack jack, const Event& event, const System& system,
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SaveKey::SaveKey(Jack jack, const Event& event, const System& system,
SaveKey::SaveKey(Jack jack, Event& event, const System& system,
const string& eepromfile)
: SaveKey(jack, event, system, eepromfile, Controller::SaveKey)
{

View File

@ -42,7 +42,7 @@ class SaveKey : public Controller
@param system The system using this controller
@param eepromfile The file containing the EEPROM data
*/
SaveKey(Jack jack, const Event& event, const System& system,
SaveKey(Jack jack, Event& event, const System& system,
const string& eepromfile);
virtual ~SaveKey();
@ -51,7 +51,7 @@ class SaveKey : public Controller
Delegating constructor currently used by both this class and classes
that inherit from SaveKey (currently, AtariVox)
*/
SaveKey(Jack jack, const Event& event, const System& system,
SaveKey(Jack jack, Event& event, const System& system,
const string& eepromfile, Type type);
public:

View File

@ -21,7 +21,7 @@
#include "Switches.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Switches::Switches(const Event& event, const Properties& properties,
Switches::Switches(Event& event, const Properties& properties,
const Settings& settings)
: myEvent(event),
mySwitches(0xFF),

View File

@ -46,7 +46,7 @@ class Switches : public Serializable
@param props The ROM properties to use for the currently enabled ROM
@param settings The settings used by the system
*/
Switches(const Event& event, const Properties& props, const Settings& settings);
Switches(Event& event, const Properties& props, const Settings& settings);
virtual ~Switches() = default;
public:
@ -124,7 +124,7 @@ class Switches : public Serializable
private:
// Reference to the event object to use
const Event& myEvent;
Event& myEvent;
// State of the console switches
uInt8 mySwitches;

View File

@ -30,7 +30,7 @@ class TrakBall : public PointingDevice
@param event The event object to use for events
@param system The system using this controller
*/
TrakBall(Jack jack, const Event& event, const System& system)
TrakBall(Jack jack, Event& event, const System& system)
: PointingDevice(jack, event, system, Controller::TrakBall,
trackballSensitivity) { }
virtual ~TrakBall() = default;