bool CWin32PowerSyscall::m_OnResume = false;
bool CWin32PowerSyscall::m_OnSuspend = false;
+bool CWin32PowerStateWorker::QueryStateChange(PowerState state)
+{
+ if (!IsRunning())
+ return false;
+
+ if (m_state.exchange(state) != state)
+ {
+ m_queryEvent.Set();
+ return true;
+ }
+
+ return false;
+}
+
+void CWin32PowerStateWorker::Process(void)
+{
+ while (!m_bStop)
+ {
+ if (AbortableWait(m_queryEvent, -1) == WAIT_SIGNALED)
+ {
+ CWIN32Util::PowerManagement(m_state.load());
+ m_state.exchange(POWERSTATE_NONE);
+ m_queryEvent.Reset();
+ }
+ }
+}
CWin32PowerSyscall::CWin32PowerSyscall()
{
+ m_worker.Create();
+}
+
+CWin32PowerSyscall::~CWin32PowerSyscall()
+{
+ if (m_worker.IsRunning())
+ m_worker.StopThread();
}
bool CWin32PowerSyscall::Powerdown()
{
- return CWIN32Util::PowerManagement(POWERSTATE_SHUTDOWN);
+ return m_worker.QueryStateChange(POWERSTATE_SHUTDOWN);
}
bool CWin32PowerSyscall::Suspend()
{
- // On Vista+, we don't receive the PBT_APMSUSPEND message as we have fired the suspend mode
- // Set the flag manually
- CWin32PowerSyscall::SetOnSuspend();
-
- return CWIN32Util::PowerManagement(POWERSTATE_SUSPEND);
+ return m_worker.QueryStateChange(POWERSTATE_SUSPEND);
}
bool CWin32PowerSyscall::Hibernate()
{
- // On Vista+, we don't receive the PBT_APMSUSPEND message as we have fired the suspend mode
- // Set the flag manually
- CWin32PowerSyscall::SetOnSuspend();
-
- return CWIN32Util::PowerManagement(POWERSTATE_HIBERNATE);
+ return m_worker.QueryStateChange(POWERSTATE_HIBERNATE);
}
bool CWin32PowerSyscall::Reboot()
{
- return CWIN32Util::PowerManagement(POWERSTATE_REBOOT);
+ return m_worker.QueryStateChange(POWERSTATE_REBOOT);
}
bool CWin32PowerSyscall::CanPowerdown()
#ifndef _WIN32_POWER_SYSCALL_H_
#define _WIN32_POWER_SYSCALL_H_
#include "powermanagement/IPowerSyscall.h"
+#include "powermanagement/PowerManager.h"
+#include "threads/Event.h"
+#include "threads/Thread.h"
+#include <atomic>
+
+class CWin32PowerStateWorker : public CThread
+{
+public:
+ CWin32PowerStateWorker() : CThread("CWin32PowerStateWorker"), m_queryEvent(true), m_state(POWERSTATE_NONE) {}
+ bool QueryStateChange(PowerState State);
+
+protected:
+ virtual void Process(void);
+ virtual void OnStartup() { SetPriority(THREAD_PRIORITY_IDLE); };
+
+private:
+ std::atomic<PowerState> m_state;
+ CEvent m_queryEvent;
+};
class CWin32PowerSyscall : public CAbstractPowerSyscall
{
public:
CWin32PowerSyscall();
+ ~CWin32PowerSyscall();
virtual bool Powerdown();
virtual bool Suspend();
static bool IsSuspending() { return m_OnSuspend; }
private:
+ CWin32PowerStateWorker m_worker;
static bool m_OnResume;
static bool m_OnSuspend;
return false;
}
- // process OnSleep() events. This is called in main thread.
- g_powerManager.ProcessEvents();
-
switch (State)
{
case POWERSTATE_HIBERNATE:
CLog::Log(LOGINFO, "Asking Windows to hibernate...");
- return SetSuspendState(true,true,false) == TRUE;
+ return SetSuspendState(true, true, false) == TRUE;
break;
case POWERSTATE_SUSPEND:
CLog::Log(LOGINFO, "Asking Windows to suspend...");
- return SetSuspendState(false,true,false) == TRUE;
+ return SetSuspendState(false, true, false) == TRUE;
break;
case POWERSTATE_SHUTDOWN:
CLog::Log(LOGINFO, "Shutdown Windows...");