Commit c4edb77d authored by Alexander A. Maly's avatar Alexander A. Maly

Fixed bug of crashing using Keyboard actor

On MacOS Catalina std::queue does not check for non-emptyness on pop().
It led to size became equal to (uint64_t) (-1) and crash when emptying
the Keyboard events queue because in LockedQueue::dequeue we always popped.
parent d45ee3b7
Pipeline #3444 passed with stages
in 4 minutes and 27 seconds
......@@ -117,15 +117,14 @@ void KeyboardModule::finalizeRun()
/* public slot */ bool KeyboardModule::runKeyHit()
{
/* алг лог клавиша нажата */
const bool result = ! buffer_.empty();
bool result = ! buffer_.empty();
return result;
}
/* public slot */ int KeyboardModule::runKeyCode()
{
/* алг цел код клавиши */
const int result = buffer_.dequeue().kumirCode;
int result = buffer_.dequeue().kumirCode;
return result;
}
......
......@@ -22,9 +22,21 @@ You should change it corresponding to functionality.
namespace ActorKeyboard
{
struct KeyEvent {
static const qint64 MAX_DELTA = 10;
int kumirCode;
qint64 timestamp;
explicit KeyEvent(int kumirCode_) : kumirCode(kumirCode_)
{
timestamp = QDateTime::currentMSecsSinceEpoch();
}
explicit KeyEvent(): kumirCode(0), timestamp(0) {}
~KeyEvent() {}
};
class KeyboardModule
: public KeyboardModuleBase
class KeyboardModule : public KeyboardModuleBase
{
Q_OBJECT
public /* methods */:
......@@ -82,28 +94,12 @@ public slots:
int runOperatorASTERISK(const int self, const ActorKeyboard::Keycode &other);
protected:
struct KeyEvent {
static const qint64 MAX_DELTA = 10;
int kumirCode;
qint64 timestamp;
inline explicit KeyEvent(int kumirCodee) : kumirCode(kumirCodee)
{
timestamp = QDateTime::currentMSecsSinceEpoch();
}
inline explicit KeyEvent(): kumirCode(0), timestamp(0) {}
};
bool eventFilter(QObject *obj, QEvent *event);
static int polyakovCodeOfKey(int qtCode, const QString &text);
kumir2::LockedQueue<KeyEvent> buffer_;
KeyEvent lastPressed_;
QMutex lastPressedLock_;
};
......
......@@ -60,25 +60,28 @@ template <typename T, class Semaphore = QSemaphore, class Mutex = QMutex>
class LockedQueue
{
public:
inline bool empty() const
bool empty() const
{
mutex_.lock();
const bool result = buffer_.empty();
bool result = buffer_.empty();
mutex_.unlock();
return result;
}
inline T dequeue()
T dequeue()
{
T result = nullitem_;
semaphore_.acquire();
mutex_.lock();
const T result = buffer_.empty() ? nullitem_ : buffer_.front();
buffer_.pop();
if (!buffer_.empty()) {
result = buffer_.front();
buffer_.pop();
}
mutex_.unlock();
return result;
}
inline void enqueue(const T &item)
void enqueue(const T &item)
{
mutex_.lock();
buffer_.push(item);
......@@ -86,23 +89,17 @@ public:
semaphore_.release();
}
// for STL iterators compatibility
inline void push_back(const T &item)
{
enqueue(item);
}
inline void reset(const T &nullitem)
void reset(const T &nullitem)
{
mutex_.lock();
nullitem_ = nullitem;
mutex_.unlock();
while (! static_cast<bool>(semaphore_.available())) {
while (! semaphore_.available()) {
semaphore_.release();
}
}
inline void clear()
void clear()
{
mutex_.lock();
while (! buffer_.empty()) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment