Skip to content

Commit

Permalink
Merge pull request #7786 from afedchin/suspend_fix_isengard
Browse files Browse the repository at this point in the history
[backport] [win32] Fix trac #16165
  • Loading branch information
MartijnKaijser committed Aug 17, 2015
2 parents 4e04d2b + 523e4db commit f32c68c
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 39 deletions.
2 changes: 0 additions & 2 deletions xbmc/ApplicationMessenger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,14 +269,12 @@ void CApplicationMessenger::ProcessMessage(ThreadMessage *pMsg)

case TMSG_HIBERNATE:
{
g_PVRManager.SetWakeupCommand();
g_powerManager.Hibernate();
}
break;

case TMSG_SUSPEND:
{
g_PVRManager.SetWakeupCommand();
g_powerManager.Suspend();
}
break;
Expand Down
30 changes: 10 additions & 20 deletions xbmc/powermanagement/PowerManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "guilib/GUIWindowManager.h"
#include "dialogs/GUIDialogBusy.h"
#include "dialogs/GUIDialogKaiToast.h"
#include "pvr/PVRManager.h"

#if defined(TARGET_DARWIN)
#include "osx/CocoaPowerSyscall.h"
Expand Down Expand Up @@ -180,31 +181,14 @@ bool CPowerManager::Powerdown()

bool CPowerManager::Suspend()
{
if (CanSuspend() && m_instance->Suspend())
{
CGUIDialogBusy* dialog = (CGUIDialogBusy*)g_windowManager.GetWindow(WINDOW_DIALOG_BUSY);
if (dialog)
dialog->Show();

return true;
}

return false;
return (CanSuspend() && m_instance->Suspend());
}

bool CPowerManager::Hibernate()
{
if (CanHibernate() && m_instance->Hibernate())
{
CGUIDialogBusy* dialog = (CGUIDialogBusy*)g_windowManager.GetWindow(WINDOW_DIALOG_BUSY);
if (dialog)
dialog->Show();

return true;
}

return false;
return (CanHibernate() && m_instance->Hibernate());
}

bool CPowerManager::Reboot()
{
bool success = CanReboot() ? m_instance->Reboot() : false;
Expand Down Expand Up @@ -254,6 +238,11 @@ void CPowerManager::ProcessEvents()
void CPowerManager::OnSleep()
{
CAnnouncementManager::Get().Announce(System, "xbmc", "OnSleep");

CGUIDialogBusy* dialog = (CGUIDialogBusy*)g_windowManager.GetWindow(WINDOW_DIALOG_BUSY);
if (dialog)
dialog->Show();

CLog::Log(LOGNOTICE, "%s: Running sleep jobs", __FUNCTION__);

// stop lirc
Expand All @@ -262,6 +251,7 @@ void CPowerManager::OnSleep()
CBuiltins::Execute("LIRC.Stop");
#endif

PVR::CPVRManager::Get().SetWakeupCommand();
g_application.SaveFileState(true);
g_application.StopPlaying();
g_application.StopShutdownTimer();
Expand Down
49 changes: 37 additions & 12 deletions xbmc/powermanagement/windows/Win32PowerSyscall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,34 +26,59 @@
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()
Expand Down
21 changes: 21 additions & 0 deletions xbmc/powermanagement/windows/Win32PowerSyscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,31 @@
#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();
Expand All @@ -48,6 +68,7 @@ class CWin32PowerSyscall : public CAbstractPowerSyscall
static bool IsSuspending() { return m_OnSuspend; }

private:
CWin32PowerStateWorker m_worker;

static bool m_OnResume;
static bool m_OnSuspend;
Expand Down
7 changes: 2 additions & 5 deletions xbmc/win32/WIN32Util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,18 +217,15 @@ bool CWIN32Util::PowerManagement(PowerState State)
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...");
Expand Down

0 comments on commit f32c68c

Please sign in to comment.