Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

WOA (Wake On Access) for sleeping media servers #1105

Closed
wants to merge 1 commit into from

4 participants

@kricker

http://trac.xbmc.org/ticket/12739

This patch allows XBMC to wake sleeping servers when needed for file playback or database updates.

@kricker kricker WOA (Wake on Access) Ticket #12739
http://trac.xbmc.org/ticket/12739

This patch allows XBMC to wake sleeping servers when needed for file playback or database updates.
2174302
@elupus
Collaborator
@t4-ravenbird

@elupus OK, I will do some refactoring and come back..
(Is it possible for me to amend this existing pull-request with my modifications or do I need to create a new PR?)

@kricker
@t4-ravenbird

IF I can update your PR directly that is probably the easiest now. In the meantime I have joined github after I found out this is where the action is..
I must make my changes first, then see what I can do with it, but any advice is appreciated

@elupus
Collaborator
@kricker

Should we remove the earlier commit prior to making a new one?

@kricker kricker closed this
@kricker kricker reopened this
@kricker

Damn, hit the wrong button on my iPod.

@elupus
Collaborator
@kricker

...runs off to read what all that means....

@t4-ravenbird

I have issued a new pull-request as replacement : #1112
Please close this one ..

@jmarshallnz jmarshallnz closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jun 28, 2012
  1. @kricker

    WOA (Wake on Access) Ticket #12739

    kricker authored
    http://trac.xbmc.org/ticket/12739
    
    This patch allows XBMC to wake sleeping servers when needed for file playback or database updates.
This page is out of date. Refresh to see the latest.
View
2  xbmc/dbwrappers/Database.cpp
@@ -392,6 +392,8 @@ bool CDatabase::Connect(const DatabaseSettings &dbSettings, bool create)
m_pDS.reset(m_pDB->CreateDataset());
m_pDS2.reset(m_pDB->CreateDataset());
+ URIUtils::WakeUpHost (dbSettings.host, "DataBase:" + dbSettings.name); // in case of mysql or other remote db
+
if (m_pDB->connect(create) != DB_CONNECTION_OK)
return false;
View
57 xbmc/settings/AdvancedSettings.cpp
@@ -877,6 +877,63 @@ void CAdvancedSettings::ParseSettingsFile(const CStdString &file)
}
}
+ // on access - wake on lan
+ TiXmlElement* pOnAccessWakeUp = pRootElement->FirstChildElement("onaccesswakeup");
+ if (pOnAccessWakeUp)
+ {
+ m_onAccessWakeUp.clear();
+ CLog::Log(LOGDEBUG,"Configuring on-access wakeup");
+ TiXmlNode* pWakeUp = pOnAccessWakeUp->FirstChildElement("wakeup");
+ while (pWakeUp)
+ {
+ CStdString strHost, strMac;
+ TiXmlNode* pHost = pWakeUp->FirstChild("host");
+ if (pHost)
+ strHost = pHost->FirstChild()->Value();
+ TiXmlNode* pMac = pWakeUp->FirstChild("mac");
+ if (pMac)
+ strMac = pMac->FirstChild()->Value();
+
+ if (strHost.IsEmpty())
+ CLog::Log(LOGERROR," Missing <host> tag");
+ else if (strMac.IsEmpty())
+ CLog::Log(LOGERROR," Missing <mac> tag");
+ else
+ {
+ int tmout = 600 ; //seconds .. 10 min default
+ {
+ const int _min = 10, _max = 12*60*60;
+
+ XMLUtils::GetInt(pWakeUp, "tmout", tmout, _min, _max);
+ }
+ int wait = 0 ; //seconds .. 0 default
+ {
+ const int _min = 0, _max = 2*60; // 2 minutes ..
+
+ XMLUtils::GetInt(pWakeUp, "wait", wait, _min, _max);
+ }
+
+ CAdvancedSettings::WakeUpEntry* entry = new CAdvancedSettings::WakeUpEntry ();
+
+ entry->host = strHost;
+ entry->mac = strMac;
+ entry->timeout_ms = tmout * 1000;
+ entry->wait_ms = wait * 1000;
+
+ CLog::Log(LOGDEBUG," Registering wakeup entry:");
+ CLog::Log(LOGDEBUG," HostName : [%s]", entry->host.c_str());
+ CLog::Log(LOGDEBUG," MacAddress : [%s]", entry->mac.c_str());
+ CLog::Log(LOGDEBUG," Timeout (sec) : [%d]", entry->timeout_ms / 1000);
+ CLog::Log(LOGDEBUG," WaitTime (sec) : [%d]", entry->wait_ms / 1000);
+
+ m_onAccessWakeUp.push_back (entry);
+ }
+
+ // get next one
+ pWakeUp = pWakeUp->NextSiblingElement("wakeup");
+ }
+ }
+
XMLUtils::GetInt(pRootElement, "remotedelay", m_remoteDelay, 1, 20);
XMLUtils::GetFloat(pRootElement, "controllerdeadzone", m_controllerDeadzone, 0.0f, 1.0f);
XMLUtils::GetInt(pRootElement, "thumbsize", m_thumbSize, 0, 1024);
View
11 xbmc/settings/AdvancedSettings.h
@@ -23,6 +23,7 @@
#include <vector>
#include "utils/StdString.h"
#include "utils/GlobalsHandling.h"
+#include "threads/SystemClock.h"
class TiXmlElement;
@@ -198,6 +199,16 @@ class CAdvancedSettings
CStdString m_tvshowMultiPartEnumRegExp;
typedef std::vector< std::pair<CStdString, CStdString> > StringMapping;
StringMapping m_pathSubstitutions;
+
+ struct WakeUpEntry
+ {
+ CStdString host, mac;
+ unsigned timeout_ms, wait_ms;
+ XbmcThreads::EndTime nextWake;
+ };
+ typedef std::vector<WakeUpEntry*> WakeUpMapping;
+ WakeUpMapping m_onAccessWakeUp; //list of 'onaccesswake' hosts
+
int m_remoteDelay; ///< \brief number of remote messages to ignore before repeating
float m_controllerDeadzone;
View
91 xbmc/utils/URIUtils.cpp
@@ -29,6 +29,9 @@
#include "network/DNSNameCache.h"
#include "settings/Settings.h"
#include "settings/AdvancedSettings.h"
+#include "guilib/GUIWindowManager.h"
+#include "dialogs/GUIDialogBusy.h"
+#include "utils/log.h"
#include "URL.h"
#include "StringUtils.h"
@@ -356,7 +359,7 @@ bool URIUtils::GetParentPath(const CStdString& strPath, CStdString& strParent)
return true;
}
-CStdString URIUtils::SubstitutePath(const CStdString& strPath)
+static CStdString SubstituteAdvancedPath (const CStdString& strPath)
{
for (CAdvancedSettings::StringMapping::iterator i = g_advancedSettings.m_pathSubstitutions.begin();
i != g_advancedSettings.m_pathSubstitutions.end(); i++)
@@ -372,6 +375,92 @@ CStdString URIUtils::SubstitutePath(const CStdString& strPath)
return strPath;
}
+static void WaitAfterWake (unsigned wait_ms)
+{
+ if (g_application.IsCurrentThread() && wait_ms > 600)
+ {
+ CSingleExit ex(g_graphicsContext);
+
+ CGUIDialogBusy* dialog = (CGUIDialogBusy*) g_windowManager.GetWindow(WINDOW_DIALOG_BUSY);
+
+ dialog->Show();
+
+ while (wait_ms > 300)
+ {
+ CSingleLock lock(g_graphicsContext);
+
+ g_windowManager.ProcessRenderLoop();
+
+ if (dialog->IsCanceled())
+ {
+ wait_ms = 0;
+ }
+ else
+ {
+ Sleep (20);
+
+ wait_ms -= 20;
+ }
+ }
+
+ dialog->Close();
+ }
+
+ Sleep (wait_ms);
+}
+
+static void WakeUp (const CStdString& mac_address, const CStdString& hostAddress, const CStdString& targetName)
+{
+ CLog::Log(LOGDEBUG,"OnAccessWakeUp [%s] trigged by accessing : %s", hostAddress.c_str(), targetName.c_str());
+
+ g_application.getNetwork().WakeOnLan(mac_address.c_str());
+}
+
+void URIUtils::WakeUpHost (const CStdString& hostName, const CStdString& targetName)
+{
+ for (CAdvancedSettings::WakeUpMapping::iterator i = g_advancedSettings.m_onAccessWakeUp.begin();
+ i != g_advancedSettings.m_onAccessWakeUp.end(); ++i)
+ {
+ CAdvancedSettings::WakeUpEntry* entry = *i;
+
+ if (hostName.CompareNoCase(entry->host) == 0)
+ {
+ // concurrency ; even if we have multiple threads coming here the worst thing
+ // that can happen is that we accidentally issue 2 wakeups
+
+ bool dowake = entry->nextWake.IsTimePast();
+
+ entry->nextWake.Set (entry->timeout_ms);
+
+ if (dowake)
+ {
+ WakeUp (entry->mac, entry->host, targetName);
+
+ WaitAfterWake (entry->wait_ms);
+ }
+
+ return; // done
+ }
+ }
+}
+
+CStdString URIUtils::SubstitutePath(const CStdString& strPath)
+{
+ CStdString realPath = SubstituteAdvancedPath (strPath);
+
+ // it is about to be accessed ; see if wakeup is required
+ {
+ CURL url (realPath);
+
+ CStdString hostName = url.GetHostName();
+
+ if (!hostName.IsEmpty())
+ WakeUpHost (hostName, realPath);
+ }
+
+ return realPath;
+}
+
bool URIUtils::IsRemote(const CStdString& strFile)
{
if (IsCDDA(strFile) || IsISO9660(strFile))
View
1  xbmc/utils/URIUtils.h
@@ -49,6 +49,7 @@ class URIUtils
static CStdString GetParentPath(const CStdString& strPath);
static bool GetParentPath(const CStdString& strPath, CStdString& strParent);
static CStdString SubstitutePath(const CStdString& strPath);
+ static void WakeUpHost(const CStdString& hostName, const CStdString& targetName);
static bool IsAddonsPath(const CStdString& strFile);
static bool IsSourcesPath(const CStdString& strFile);
Something went wrong with that request. Please try again.