diff -rupN xbmc-upstream/xbmc/Application.cpp xbmc-vbs/xbmc/Application.cpp --- xbmc-upstream/xbmc/Application.cpp 2013-06-12 00:24:40.486262597 +0200 +++ xbmc-vbs/xbmc/Application.cpp 2013-06-12 01:23:11.948400122 +0200 @@ -5907,3 +5907,37 @@ CPerformanceStats &CApplication::GetPerf } #endif +void CApplication::CloseNetworkShares() +{ + CLog::Log(LOGDEBUG,"CApplication::CloseNetworkShares: Closing all network shares"); + +#if defined(HAS_FILESYSTEM_SMB) && !defined(_WIN32) + smb.Deinit(); +#endif + +#if defined(HAS_FILESYSTEM_NFS) + gNfsConnection.Deinit(); +#endif +} + +void CApplication::StopAddonServices() +{ + CLog::Log(LOGDEBUG,"CApplication::StopAddonServices"); + CAddonMgr::Get().StopServices(false); +} + +void CApplication::StartAddonServices() +{ + CLog::Log(LOGDEBUG,"CApplication::StartAddonServices - before login services"); + + //we start all services that run before login + CAddonMgr::Get().StartServices(true); + + //this is meant to find out if we are logged in already + //so only start after-login services if we are not seeing the login screen + if (g_windowManager.GetActiveWindow() != WINDOW_LOGIN_SCREEN) + { + CLog::Log(LOGDEBUG,"CApplication::StartAddonServices - No login screen? So starting after-login-services also"); + CAddonMgr::Get().StartServices(false); + } +} diff -rupN xbmc-upstream/xbmc/Application.h xbmc-vbs/xbmc/Application.h --- xbmc-upstream/xbmc/Application.h 2013-06-12 00:24:40.494262695 +0200 +++ xbmc-vbs/xbmc/Application.h 2013-06-12 01:15:31.530852337 +0200 @@ -204,6 +204,9 @@ public: void CheckPlayingProgress(); void CheckAudioScrobblerStatus(); void ActivateScreenSaver(bool forceType = false); + void CloseNetworkShares(); + void StartAddonServices(); + void StopAddonServices(); virtual void Process(); void ProcessSlow(); diff -rupN xbmc-upstream/xbmc/filesystem/SmbFile.cpp xbmc-vbs/xbmc/filesystem/SmbFile.cpp --- xbmc-upstream/xbmc/filesystem/SmbFile.cpp 2013-06-12 00:24:40.962268274 +0200 +++ xbmc-vbs/xbmc/filesystem/SmbFile.cpp 2013-06-12 01:23:11.948400122 +0200 @@ -92,6 +92,7 @@ void CSMB::Deinit() void CSMB::Init() { CSingleLock lock(*this); + if (!m_context) { #ifdef TARGET_POSIX diff -rupN xbmc-upstream/xbmc/filesystem/NFSFile.cpp xbmc-vbs/xbmc/filesystem/NFSFile.cpp --- xbmc-upstream/xbmc/filesystem/NFSFile.cpp 2013-07-12 22:18:51.062605410 +0200 +++ xbmc-vbs/xbmc/filesystem/NFSFile.cpp 2013-07-12 22:19:27.069861082 +0200 @@ -308,6 +308,8 @@ void CNfsConnection::Deinit() { + CLog::Log(LOGNOTICE,"CNfsConnection::Deinit"); + if(m_pNfsContext && m_pLibNfs->IsLoaded()) { destroyOpenContexts(); diff -rupN xbmc-upstream/xbmc/powermanagement/PowerManager.cpp xbmc-vbs/xbmc/powermanagement/PowerManager.cpp --- xbmc-upstream/xbmc/powermanagement/PowerManager.cpp 2013-06-12 00:24:41.634276292 +0200 +++ xbmc-vbs/xbmc/powermanagement/PowerManager.cpp 2013-06-12 01:15:32.166859998 +0200 @@ -23,6 +23,7 @@ #include "Application.h" #include "cores/AudioEngine/AEFactory.h" #include "input/KeyboardStat.h" +#include "network/Network.h" #include "settings/GUISettings.h" #include "windowing/WindowingFactory.h" #include "utils/log.h" @@ -32,6 +33,7 @@ #include "guilib/LocalizeStrings.h" #include "guilib/GraphicContext.h" #include "dialogs/GUIDialogKaiToast.h" +#include "settings/AdvancedSettings.h" #ifdef HAS_LCD #include "utils/LCDFactory.h" @@ -146,12 +148,22 @@ bool CPowerManager::Powerdown() bool CPowerManager::Suspend() { - return CanSuspend() ? m_instance->Suspend() : false; + if (!CanSuspend()) + return false; + + OnPrepareSleep(); + + return m_instance->Suspend(); } bool CPowerManager::Hibernate() { - return CanHibernate() ? m_instance->Hibernate() : false; + if (!CanHibernate()) + return false; + + OnPrepareSleep(); + + return m_instance->Hibernate(); } bool CPowerManager::Reboot() { @@ -188,6 +200,16 @@ void CPowerManager::ProcessEvents() m_instance->PumpPowerEvents(this); } +void CPowerManager::OnPrepareSleep() +{ + CLog::Log(LOGNOTICE, "%s: Preparing sleep", __FUNCTION__); + + //stop all addon services here + //we do this here instead in OnSleep cause according to DBUS specification we only have 1 second of time in OnSleep + //so shutdowns that may potentially take longer should be issued in here + g_application.StopAddonServices(); +} + void CPowerManager::OnSleep() { CAnnouncementManager::Announce(System, "xbmc", "OnSleep"); @@ -207,13 +229,41 @@ void CPowerManager::OnSleep() g_application.StopPlaying(); g_application.StopShutdownTimer(); g_application.StopScreenSaverTimer(); + g_application.CloseNetworkShares(); CAEFactory::Suspend(); } +void CPowerManager::WaitForNet() +{ + CLog::Log(LOGDEBUG, "%s: Waithing for first NIC to come up", __FUNCTION__); + + const unsigned maxLoopCount = 50u; + const unsigned sleepTimeMs = 200u; + + for(unsigned i=0; i < 50; ++i) + { + CNetworkInterface* pIface = g_application.getNetwork().GetFirstConnectedInterface(); + if (pIface && pIface->IsEnabled() && pIface->IsConnected()) + { + CLog::Log(LOGDEBUG, "%s: NIC is up after waiting %d ms", __FUNCTION__, i * sleepTimeMs); + return; + } + + Sleep(sleepTimeMs); + } + + CLog::Log(LOGDEBUG, "%s: NIC did not come up within %d ms... Lets give up...", __FUNCTION__, maxLoopCount * sleepTimeMs); +} + void CPowerManager::OnWake() { CLog::Log(LOGNOTICE, "%s: Running resume jobs", __FUNCTION__); + WaitForNet(); + + //re-start addon services + g_application.StartAddonServices(); + // reset out timers g_application.ResetShutdownTimers(); @@ -248,6 +298,7 @@ void CPowerManager::OnWake() #endif CAEFactory::Resume(); + g_application.UpdateLibraries(); g_weatherManager.Refresh(); diff -rupN xbmc-upstream/xbmc/powermanagement/PowerManager.h xbmc-vbs/xbmc/powermanagement/PowerManager.h --- xbmc-upstream/xbmc/powermanagement/PowerManager.h 2013-06-12 00:24:41.634276292 +0200 +++ xbmc-vbs/xbmc/powermanagement/PowerManager.h 2013-06-12 01:15:32.166859998 +0200 @@ -67,11 +67,14 @@ public: void ProcessEvents(); private: + void OnPrepareSleep(); void OnSleep(); void OnWake(); void OnLowBattery(); + void WaitForNet(); + IPowerSyscall *m_instance; };