chore: Switched event buffer from Carbon to GCD

This commit is contained in:
Stephen Jensen
2025-01-26 13:12:11 -06:00
committed by Nick Bolton
parent 415fc3ea63
commit 30a37a8a50
2 changed files with 56 additions and 64 deletions

View File

@ -1,6 +1,7 @@
/*
* Deskflow -- mouse and keyboard sharing utility
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
* SPDX-FileCopyrightText: (C) 2025 Stephen Jensen <sjensen313@proton.me>
* SPDX-FileCopyrightText: (C) 2012 - 2025 Symless Ltd.
* SPDX-FileCopyrightText: (C) 2004 Chris Schoeneman
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
*/
@ -9,6 +10,7 @@
#include "base/Event.h"
#include "base/IEventQueue.h"
#include "base/Log.h"
//
// EventQueueTimer
@ -22,86 +24,70 @@ class EventQueueTimer
// OSXEventQueueBuffer
//
OSXEventQueueBuffer::OSXEventQueueBuffer(IEventQueue *events)
: m_event(NULL),
m_eventQueue(events),
m_carbonEventQueue(NULL)
OSXEventQueueBuffer::OSXEventQueueBuffer(IEventQueue *events) : m_eventQueue(events)
{
// do nothing
// Initialization is now managed using modern constructs
}
OSXEventQueueBuffer::~OSXEventQueueBuffer()
{
// release the last event
if (m_event != NULL) {
ReleaseEvent(m_event);
}
// No explicit clean-up needed as GCD and STL handle resource management
}
void OSXEventQueueBuffer::init()
{
m_carbonEventQueue = GetCurrentEventQueue();
// No initialization needed for GCD-based implementation
}
void OSXEventQueueBuffer::waitForEvent(double timeout)
{
EventRef event;
ReceiveNextEvent(0, NULL, timeout, false, &event);
std::unique_lock<std::mutex> lock(m_mutex);
if (m_dataQueue.empty()) {
auto duration = std::chrono::duration<double>(timeout);
LOG_DEBUG2("waiting for event, timeout: %f seconds", timeout);
m_cond.wait_for(lock, duration, [this] { return !m_dataQueue.empty(); });
} else {
LOG_DEBUG2("found events in the queue");
}
}
IEventQueueBuffer::Type OSXEventQueueBuffer::getEvent(Event &event, uint32_t &dataID)
{
// release the previous event
if (m_event != NULL) {
ReleaseEvent(m_event);
m_event = NULL;
}
// get the next event
OSStatus error = ReceiveNextEvent(0, NULL, 0.0, true, &m_event);
// handle the event
if (error == eventLoopQuitErr) {
event = Event(Event::kQuit);
return kSystem;
} else if (error != noErr) {
std::unique_lock<std::mutex> lock(m_mutex);
if (m_dataQueue.empty()) {
LOG_DEBUG2("no events in queue");
return kNone;
} else {
uint32_t eventClass = GetEventClass(m_event);
switch (eventClass) {
case 'Syne':
dataID = GetEventKind(m_event);
return kUser;
default:
event = Event(Event::kSystem, m_eventQueue->getSystemTarget(), &m_event);
return kSystem;
}
}
dataID = m_dataQueue.front();
m_dataQueue.pop();
lock.unlock(); // Unlock early to allow other threads to proceed
LOG_DEBUG2("handled user event with dataID: %u", dataID);
return kUser;
}
bool OSXEventQueueBuffer::addEvent(uint32_t dataID)
{
EventRef event;
OSStatus error = CreateEvent(kCFAllocatorDefault, 'Syne', dataID, 0, kEventAttributeNone, &event);
// Use GCD to dispatch event addition on the main queue
dispatch_async(dispatch_get_main_queue(), ^{
std::lock_guard<std::mutex> lock(this->m_mutex);
LOG_DEBUG2("adding user event with dataID: %u", dataID);
this->m_dataQueue.push(dataID);
this->m_cond.notify_one();
LOG_DEBUG2("user event added to queue, dataID=%u", dataID);
});
if (error == noErr) {
assert(m_carbonEventQueue != NULL);
error = PostEventToQueue(m_carbonEventQueue, event, kEventPriorityStandard);
ReleaseEvent(event);
}
return (error == noErr);
// Always return true since dispatch_async does not fail under normal conditions
return true;
}
bool OSXEventQueueBuffer::isEmpty() const
{
EventRef event;
OSStatus status = ReceiveNextEvent(0, NULL, 0.0, false, &event);
return (status == eventLoopTimedOutErr);
std::lock_guard<std::mutex> lock(m_mutex);
bool empty = m_dataQueue.empty();
LOG_DEBUG2("queue is %s", empty ? "empty" : "not empty");
return empty;
}
EventQueueTimer *OSXEventQueueBuffer::newTimer(double, bool) const