lib/platform: Use standard mutex primitives in OSX screen code

This commit is contained in:
Povilas Kanapickas 2021-11-03 02:58:35 +02:00
parent 9df64f36e3
commit da673de27c
2 changed files with 31 additions and 51 deletions

View File

@ -25,7 +25,6 @@
#include "common/stdmap.h" #include "common/stdmap.h"
#include "common/stdvector.h" #include "common/stdvector.h"
#include <bitset>
#include <Carbon/Carbon.h> #include <Carbon/Carbon.h>
#include <mach/mach_port.h> #include <mach/mach_port.h>
#include <mach/mach_interface.h> #include <mach/mach_interface.h>
@ -33,22 +32,21 @@
#include <IOKit/pwr_mgt/IOPMLib.h> #include <IOKit/pwr_mgt/IOPMLib.h>
#include <IOKit/IOMessage.h> #include <IOKit/IOMessage.h>
#include <condition_variable>
#include <bitset>
#include <mutex>
extern "C" { extern "C" {
typedef int CGSConnectionID; typedef int CGSConnectionID;
CGError CGSSetConnectionProperty(CGSConnectionID cid, CGSConnectionID targetCID, CFStringRef key, CFTypeRef value); CGError CGSSetConnectionProperty(CGSConnectionID cid, CGSConnectionID targetCID, CFStringRef key, CFTypeRef value);
int _CGSDefaultConnection(); int _CGSDefaultConnection();
} }
template <class T>
class CondVar;
class EventQueueTimer; class EventQueueTimer;
class Mutex;
class Thread; class Thread;
class OSXKeyState; class OSXKeyState;
class OSXScreenSaver; class OSXScreenSaver;
class IEventQueue; class IEventQueue;
class Mutex;
//! Implementation of IPlatformScreen for OS X //! Implementation of IPlatformScreen for OS X
class OSXScreen : public PlatformScreen { class OSXScreen : public PlatformScreen {
@ -304,9 +302,10 @@ private:
EventHandlerRef m_switchEventHandlerRef; EventHandlerRef m_switchEventHandlerRef;
// sleep / wakeup // sleep / wakeup
Mutex* m_pmMutex; std::mutex pm_mutex_;
Thread* m_pmWatchThread; Thread* m_pmWatchThread;
CondVar<bool>* m_pmThreadReady; std::condition_variable pm_thread_ready_cv_;
bool is_pm_thread_ready_ = false;
CFRunLoopRef m_pmRunloop; CFRunLoopRef m_pmRunloop;
io_connect_t m_pmRootPort; io_connect_t m_pmRootPort;
@ -341,8 +340,9 @@ private:
std::string m_dropTarget; std::string m_dropTarget;
#if defined(MAC_OS_X_VERSION_10_7) #if defined(MAC_OS_X_VERSION_10_7)
Mutex* m_carbonLoopMutex; mutable std::mutex carbon_loop_mutex_;
CondVar<bool>* m_carbonLoopReady; mutable std::condition_variable cardon_loop_ready_cv_;
bool is_carbon_loop_ready_ = false;
#endif #endif
class OSXScreenImpl* m_impl; class OSXScreenImpl* m_impl;

View File

@ -31,8 +31,6 @@
#include "barrier/KeyMap.h" #include "barrier/KeyMap.h"
#include "barrier/ClientApp.h" #include "barrier/ClientApp.h"
#include "mt/CondVar.h" #include "mt/CondVar.h"
#include "mt/Lock.h"
#include "mt/Mutex.h"
#include "mt/Thread.h" #include "mt/Thread.h"
#include "arch/XArch.h" #include "arch/XArch.h"
#include "base/Log.h" #include "base/Log.h"
@ -87,9 +85,7 @@ OSXScreen::OSXScreen(IEventQueue* events, bool isPrimary, bool autoShowHideCurso
m_hiddenWindow(NULL), m_hiddenWindow(NULL),
m_userInputWindow(NULL), m_userInputWindow(NULL),
m_switchEventHandlerRef(0), m_switchEventHandlerRef(0),
m_pmMutex(new Mutex),
m_pmWatchThread(NULL), m_pmWatchThread(NULL),
m_pmThreadReady(new CondVar<bool>(m_pmMutex, false)),
m_pmRootPort(0), m_pmRootPort(0),
m_activeModifierHotKey(0), m_activeModifierHotKey(0),
m_activeModifierHotKeyMask(0), m_activeModifierHotKeyMask(0),
@ -150,11 +146,7 @@ OSXScreen::OSXScreen(IEventQueue* events, bool isPrimary, bool autoShowHideCurso
&OSXScreen::handleConfirmSleep)); &OSXScreen::handleConfirmSleep));
// create thread for monitoring system power state. // create thread for monitoring system power state.
*m_pmThreadReady = false; is_pm_thread_ready_ = false;
#if defined(MAC_OS_X_VERSION_10_7)
m_carbonLoopMutex = new Mutex();
m_carbonLoopReady = new CondVar<bool>(m_carbonLoopMutex, false);
#endif
LOG((CLOG_DEBUG "starting watchSystemPowerThread")); LOG((CLOG_DEBUG "starting watchSystemPowerThread"));
m_pmWatchThread = new Thread([this](){ watchSystemPowerThread(); }); m_pmWatchThread = new Thread([this](){ watchSystemPowerThread(); });
} }
@ -190,10 +182,8 @@ OSXScreen::~OSXScreen()
if (m_pmWatchThread) { if (m_pmWatchThread) {
// make sure the thread has setup the runloop. // make sure the thread has setup the runloop.
{ {
Lock lock(m_pmMutex); std::unique_lock<std::mutex> lock(pm_mutex_);
while (!(bool)*m_pmThreadReady) { pm_thread_ready_cv_.wait(lock, [this](){ return is_pm_thread_ready_; });
m_pmThreadReady->wait();
}
} }
// now exit the thread's runloop and wait for it to exit // now exit the thread's runloop and wait for it to exit
@ -203,8 +193,6 @@ OSXScreen::~OSXScreen()
delete m_pmWatchThread; delete m_pmWatchThread;
m_pmWatchThread = NULL; m_pmWatchThread = NULL;
} }
delete m_pmThreadReady;
delete m_pmMutex;
m_events->removeHandler(m_events->forOSXScreen().confirmSleep(), m_events->removeHandler(m_events->forOSXScreen().confirmSleep(),
getEventTarget()); getEventTarget());
@ -215,11 +203,6 @@ OSXScreen::~OSXScreen()
delete m_keyState; delete m_keyState;
delete m_screensaver; delete m_screensaver;
#if defined(MAC_OS_X_VERSION_10_7)
delete m_carbonLoopMutex;
delete m_carbonLoopReady;
#endif
} }
void* void*
@ -1638,13 +1621,13 @@ void OSXScreen::watchSystemPowerThread()
// thread is ready // thread is ready
{ {
Lock lock(m_pmMutex); std::lock_guard<std::mutex> lock(pm_mutex_);
*m_pmThreadReady = true; is_pm_thread_ready_ = true;
m_pmThreadReady->signal(); pm_thread_ready_cv_.notify_one();
} }
// if we were unable to initialize then exit. we must do this after // if we were unable to initialize then exit. we must do this after
// setting m_pmThreadReady to true otherwise the parent thread will // setting is_pm_thread_ready_ to true otherwise the parent thread will
// block waiting for it. // block waiting for it.
if (m_pmRootPort == 0) { if (m_pmRootPort == 0) {
LOG((CLOG_WARN "failed to init watchSystemPowerThread")); LOG((CLOG_WARN "failed to init watchSystemPowerThread"));
@ -1657,16 +1640,16 @@ void OSXScreen::watchSystemPowerThread()
m_events->waitForReady(); m_events->waitForReady();
#if defined(MAC_OS_X_VERSION_10_7) #if defined(MAC_OS_X_VERSION_10_7)
{ {
Lock lockCarbon(m_carbonLoopMutex); std::lock_guard<std::mutex> lock_carbon(carbon_loop_mutex_);
if (*m_carbonLoopReady == false) { if (!is_carbon_loop_ready_) {
// we signalling carbon loop ready before starting // we signalling carbon loop ready before starting
// unless we know how to do it within the loop // unless we know how to do it within the loop
LOG((CLOG_DEBUG "signalling carbon loop ready")); LOG((CLOG_DEBUG "signalling carbon loop ready"));
*m_carbonLoopReady = true; is_carbon_loop_ready_ = true;
m_carbonLoopReady->signal(); cardon_loop_ready_cv_.notify_one();
} }
} }
#endif #endif
@ -1684,7 +1667,7 @@ void OSXScreen::watchSystemPowerThread()
CFRelease(runloopSourceRef); CFRelease(runloopSourceRef);
} }
Lock lock(m_pmMutex); std::lock_guard<std::mutex> lock(pm_mutex_);
IODeregisterForSystemPower(&notifier); IODeregisterForSystemPower(&notifier);
m_pmRootPort = 0; m_pmRootPort = 0;
LOG((CLOG_DEBUG "stopped watchSystemPowerThread")); LOG((CLOG_DEBUG "stopped watchSystemPowerThread"));
@ -1721,7 +1704,7 @@ OSXScreen::handlePowerChangeRequest(natural_t messageType, void* messageArg)
break; break;
} }
Lock lock(m_pmMutex); std::lock_guard<std::mutex> lock(pm_mutex_);
if (m_pmRootPort != 0) { if (m_pmRootPort != 0) {
IOAllowPowerChange(m_pmRootPort, (long)messageArg); IOAllowPowerChange(m_pmRootPort, (long)messageArg);
} }
@ -1732,7 +1715,7 @@ OSXScreen::handleConfirmSleep(const Event& event, void*)
{ {
long messageArg = (long)event.getData(); long messageArg = (long)event.getData();
if (messageArg != 0) { if (messageArg != 0) {
Lock lock(m_pmMutex); std::lock_guard<std::mutex> lock(pm_mutex_);
if (m_pmRootPort != 0) { if (m_pmRootPort != 0) {
// deliver suspend event immediately. // deliver suspend event immediately.
m_events->addEvent(Event(m_events->forIScreen().suspend(), m_events->addEvent(Event(m_events->forIScreen().suspend(),
@ -2093,22 +2076,19 @@ void
OSXScreen::waitForCarbonLoop() const OSXScreen::waitForCarbonLoop() const
{ {
#if defined(MAC_OS_X_VERSION_10_7) #if defined(MAC_OS_X_VERSION_10_7)
if (*m_carbonLoopReady) { if (is_carbon_loop_ready_) {
LOG((CLOG_DEBUG "carbon loop already ready")); LOG((CLOG_DEBUG "carbon loop already ready"));
return; return;
} }
Lock lock(m_carbonLoopMutex); std::unique_lock<std::mutex> lock(carbon_loop_mutex_);
LOG((CLOG_DEBUG "waiting for carbon loop")); LOG((CLOG_DEBUG "waiting for carbon loop"));
double timeout = ARCH->time() + kCarbonLoopWaitTimeout; while (!cardon_loop_ready_cv_.wait_for(lock, std::chrono::seconds{kCarbonLoopWaitTimeout},
while (!m_carbonLoopReady->wait()) { [this](){ return is_carbon_loop_ready_; })) {
if (ARCH->time() > timeout) { LOG((CLOG_DEBUG "carbon loop not ready, waiting again"));
LOG((CLOG_DEBUG "carbon loop not ready, waiting again")); }
timeout = ARCH->time() + kCarbonLoopWaitTimeout;
}
}
LOG((CLOG_DEBUG "carbon loop ready")); LOG((CLOG_DEBUG "carbon loop ready"));
#endif #endif