Bugzilla – Bug 8520
Prevent Standby Plugin does not take in to account Windows's 2-minute WoL timeout behaviour
Last modified: 2010-01-02 00:50:03 UTC
As discussed in several places: http://forums.slimdevices.com/showthread.php?p=313768 http://forums.slimdevices.com/showpost.php?p=102397&postcount=30 http://forums.slimdevices.com/showpost.php?p=48087&postcount=21 , Windows will go to sleep after 2 minutes when resumed from S3 by WoL. This causes the user-unfriendly behaviour of the player going 'off' when browsing for music (but not playing) for more than 2 minutes after a WoL resume. The 2-minute timeout is separate to the configured system idle time (1 hour in Windows Vista) and is not configurable. The attached patch alters the current behaviour (which is to prevent sleep only when any player is playing) to prevent sleep when any player is on. I'm also using the PowerSave plugin to power off the player when paused or stopped for more than 15 minutes. This way, the server will automatically sleep after 15 + server-system-sleep-timeout in a predicable way. The patch is bound to have problems (as KDF says in the first link), but it's more of one that works for me and illustrates a new behviour solves a problem with the current one.
Created attachment 3469 [details] Prevents standby when any players are powered on
nigel, does it PERMANENTLY prevent going into standby? i agree 2min is too short, but if it permanently prevents it, thats no good either imo.
Depends what you mean by permanently. ;-) Without the PowerSave plugin, the server will stay on so long as at least one player is powered on. The PowerSave plugin will power off a player after a set peroid of inactivity. Together, it's not permanent. One thought I just had - is a SBC classed as a player as far as this and the PowerSave plugins are concerned? (I've not got one).
the roadmap says the sbc will be a player come 7.2 here is where i think there's an issue with what you are doing... just b/c i leave on a SB or SBC or whatever, doesn't necessarily mean i want the computer running SC to stay on. in other words, i don't want the computer on indefinitely just b/c my SB2 is on but not playing anything, after say, 25min or so... i think some configuration options need to be implemented. now, i may be confused about what all exactly you are trying to do, and i don't use the powersave plugin... but if i do a WoL i agree that 2min to go back to sleep is too soon if i'm not playing anything but the SB is on. but if its 25min later and i'm not playing anything and the SB is on, then i would want the computer to go back to sleep. am i making sense?
I don't think this is going to make the cutoff for 7.2. Chris to test the patch though and read the comments to try and form an opinion.
Mike: In essence, you're doing the same as I am. After a period (e.g. 25 minutes) of not playing music (so either paused or stopped), your server is sleeping. The user experience is that the player has turned off (at the same time as the server). For me, the Prevent Standgy plugin (with patch) keeps the server alive so long as at least one player is on. The Power Save plugin will power a player off after a period (I set it to 15 minutes) of inactivity (activity defined as user input and - how I've configured it - playing but not paused or stopped). After 15 minutes, the player is powered off automatically and after the OS sleep timeout (say 1 hour) the server powers off. This de-coupling of the player/user experience and server can be useful. Players can be powered off automatically in line with how the user wants it (I don't like to see powered off players scrolling the Now Playing screen for ages after the music has stopped) and the server can sleep in line with OS requirements (e.g. Vista performs background tasks like defrag in idle time). Without the patch (and to best effect, the Power Save plugin), in order to fix the two minute problem the server would have to keep the server alive when: - playing - paused or stopped when the user is active on any player, with a timeout equal to the OS sleep timeout (so query the OS for this). I agree - it should be configurable when the server sleeps (paused and stopped, or just stopped). With the patch and Power Save plugin, this is in effect done byt the Power Save plugin.
Ping chris.
That patch no longer works for 7.3, and I'm not sure you should be using the button mode there. Can you find another way to do it?
I'm sure the patch is less than ideal. :-) I'm no programmer, and more problematic is that I just don't have the time to dedicate to this these days (hey, children!). I just tried to find a quick hack to fix the problem and give a consistent behaviour as far as the user was concerned. I should note that since I started to use the modified plugin, I have seen (albeit infrequently) the server go to sleep even though at least one player has been powered on. I *think* that lowering the $interval to 30 seconds helped (it reduced the incidence but I have still seen the problem after) but it shouldn't have since the default $interval is 1 minute and the Windows WoL timeout is 2 minutes. Perhaps KDF's point about hard-coded modes is important here (http://forums.slimdevices.com/showpost.php?p=48087&postcount=21 )?
Created attachment 4448 [details] Updated patch for v7.3 Uses the same method as the previous patch.
I have a different proposed fix for this. See the attached zip file (not a patch) which contains a rewrite of the PreventStandby plugin.
Created attachment 4538 [details] Zip file with proposed rewrite of PreventStandby
Gordon - would you describe how your version of the plugin changes the current behavior (or differs from my patch)? I've not looked at it - so just being (slightly) lazy. Thanks.
We're happy to consider putting in this change at some point, but I'm moving the target so that it doesn't hold up any upcoming releases.
Text of an email I sent to Nigel back on 20090105: I rewrote PreventStandby before I was aware of your bug report here or your proposed patch. KDF pointed out this bug report to me and so I posted my code for consideration. I didn't intend to hijack your bug report. It may be that your proposed patch is all that is required to address this issue. The version I came up with makes PreventStandby work a little harder. When the timer code gets executed, it checks for the following states: Players playing, players updating (firmware updates) the scanner running and it detects if the system has recently resumed from standby or hibernation. If any of these conditions are met, the timer code zeros a countup variable that otherwise gets incremented every minute. That countup variable is checked against a timeout variable that can be set via a settings page I added to the plugin so that the user can specify how long of a time out after playing stops, etc. the system will continue to call SetThreadExecutionState and thus prevent standby. The default that I put in is 20 minutes. I came up with this PreventStandby rewrite after I realized that any attempt I made to address this problem in my SrvrPowerCtrl plugin would just be a kludge. It really needed to be addressed in PreventStandby.
Gordon - please keep us up to date with your version of the plugin. Chris - If the old plugin is broken then we should investigate this issue for the next release. Or take out the plugin. But there's no reason to leave a broken plugin in the release. Can you/QA reproduce the original issue?
Michael: the currently released PreventStandby isn't "broken" per se -- it just fails to address Window's annoying habit of slipping back into standby two minutes after a WOL or a RTC wakeup if the user doesn't get content cued up and playing within that short time frame. So the proposed changes are enhancements. As far as QA verifying that this is an issue: put a windows machine into standby, wait a couple of minutes, WOL it, and then do nothing. The machine will revert to standby approximately two minutes later. See Microsoft's rather strange take on this: http://support.microsoft.com/kb/810719 Even if one follows MS's directions in that support note, the server will always revert to standby two minutes after a WOL if there is no activity on the server, no matter how one has configured the system's power management settings, the NIC's pm settings, etc. This proposed enhancement to PreventStandby specifically tries to address this rather infamous windows annoyance. Apesbrain has suggested a couple of changes to my mangled syntax in strings.txt. I also thought I would try to incorporate Nigel's feature -- optionally prevent standby if any players are "on" -- albeit via another method. I'll post those changes in a bit.
OK, here are the changes I mentioned.
Created attachment 4621 [details] Zip file with further proposed changes to PreventStandby
Gordon - thanks for your explanation. Your patch looks to be a much more complete solution than mine. Adding detection of players being "on" would only add the ability to keep the server alive when players are paused. For my usage case, this isn't required. All I'd need to do is to set your patch timeout to be longer (e.g. the 20 minute default) than than the PowerSave plugin timeout I have set (15 minutes). Thus paused players are turned off after 15 minutes (even from paused) and amplifiers/speakers are turned off (via IR Blaster or XPL/X.10) before the server is allowed to sleep. One case that your patch might not cover is other plugins performing actions that need the server to be awake. Specifically, I'm thinking here of the Lazy Search plugin's 'lazyfication' scan/work. I wonder if there'd be a way of providing an API for a plugin to use so that it can register that the server should be kept awake (and de-register this when the finished). I'm not sure of the correct terminology, so I hope that makes sense.
Gordon - is the attached patch still the latest version? I think we should get this in to 7.4 now.
The 2nd zip contains the latest code. But Nigel didn't see the need for the last enhancement that I added: optionally preventing standby if any players are ON, not just playing...with an associated checkbox setting on the settings page. This option is not on by default and it doesn't add much in the way of code bloat. Do you think it's OK to just leave it in? If not, I'll be happy to make another version that strips that option out of the code and off the settings page. Somebody at LogiTech should really look over the strings.txt file. There may be a much simpler way of expressing some of the statements in there. Also, strings.txt will need translations to languages other than EN.
Created attachment 4838 [details] Slightly re-arranged version Could you please give the attached version some testing? I've slightly re-organized the code and removed some of the global variables.
quick questions: will this code apply to all versions of windows? mainly, XP, Vista, and 7 whenever it comes out, plus their variations? (also, if SC remains 32bit, will 32bit SC power saving code be compatible with a 64bit OS?)
Michael: I'm sorry it's taking me so long to test this. I have my windows machines all torn down at the moment and I need to reinstall XP and SC. Please give me a little time here.
I've not used Gordon's version before, but I've just removed my patch and installed his. I'll report back in a day or so. I vote for keeping the "when powered on" option - someone is bound to have a use for it.
Michael: your version tests out just fine. On a windows box with a brand new XP pro SP3 install, the plugin worked as expected. Also, thanks for the clean up...and it's instructive to see what you did with the code. I do have a couple of questions, if you don't mind...and forgive me, my perl ignorance is on parade here: 1). How does perl implement constants? Is a perl constant really any different than a global variable, memory wise? 2). I can understand the desire to reduce the number of global vars. But why get a new reference to SetThreadExecutionState every minute? Is there a concern that a reference to a kernel function will get "stale"? 3). What is the convention for prefixing the naming of some functions with the underscore, i.e. _playersBusy, _hasRusumed? Why those functions and not others? Again, thanks for massaging this...and sorry it took me as long as it did to conduct all the tests.
Thanks for testing, Gordon! I answered the unrelated questions in a PM to keep the bug report as clutter free as possible. Change 25127 - apply Gordon's modified patch to fix standby after waking up behaviour.
Sorry, Michael. If you sent me a PM, I didn't get it.
> Sorry, Michael. If you sent me a PM, I didn't get it. Sent the following to the address you're using in bugzilla: > 1). How does perl implement constants? Is a perl constant really any > different than a global variable, memory wise? From http://perldoc.perl.org/constant.html: "When a constant is used in an expression, perl replaces it with its value at compile time, and may then optimize the expression further." IMHO it's less about memory consumption, but runtime optimization. Eg. in our case we're doing calculations with a value. If this was a variable, the calculation (eg. we're using "INTERVAL * 2") would have to be done each time at runtime, as the variable might have changed. Using a constant, this can be done at compile time. There's little advantage in our case, as other variables are involved too. But in other cases it's more important. > 2). I can understand the desire to reduce the number of global vars. But why > get a new reference to SetThreadExecutionState every minute? Is there a > concern that a reference to a kernel function will get "stale"? IMHO it doesn't hurt performance wise, and there's less risk of having a variable leaking. > 3). What is the convention for prefixing the naming of some functions with > the underscore, i.e. _playersBusy, _hasRusumed? Why those functions and > not others? It's a gut decision of mine :-). I do this for "inner functions". I doubt there's a hard rule. As a convention such functions should never be called by anything outside the current module.
This bug has been marked as fixed in the 7.4.0 release version of SqueezeBox Server! * SqueezeCenter: 28672 * Squeezebox 2 and 3: 130 * Transporter: 80 * Receiver: 65 * Boom: 50 * Controller: 7790 * Radio: 7790 Please see the Release Notes for all the details: http://wiki.slimdevices.com/index.php/Release_Notes If you haven't already, please download and install the new version from http://www.logitechsqueezebox.com/support/download-squeezebox-server.html If you are still experiencing this problem, feel free to reopen the bug with your new comments and we'll have another look.
I'd like to propose a further tweak to the PreventStandby plugin. I've gotten one report of this plugin failing with Windows 7, though this may be due to the user's use of the 3rd party 'MCE Standby Tool' utility ( http://slicksolutions.eu/mst.shtml ) which seems to tell the system to ignore SetThreadExecutionState calls. I've also observed on my own Windows 7 machine that the Plugin often seems to fail to realize that the machine has resumed from sleep. I propose that two lines in Plugin.pm get changed: Line 106 be changed from: if ( Slim::Music::Import->stillScanning() || _hasResumed($currenttime) || _playersBusy() ) { ..to: if ( _hasResumed($currenttime) || _playersBusy() || Slim::Music::Import->stillScanning() ) { ..and line 176 be changed from: if ( $currenttime > ($lastchecktime + (INTERVAL * 2)) || $currenttime < $lastchecktime ) { ..to: if ( $currenttime > ($lastchecktime + INTERVAL + 5) || $currenttime < $lastchecktime ) { With these changes, PreventStandby seems to work more reliably with my Windows 7 setup. Also, I was going to propose that strings.txt be changed so that the plugin more closely matches the terseness of the other stock plugins. But I see that someone actually went to the trouble of translating my chattiness into several other languages...so...never mind on that one.
perhaps you will need to open a new bug for this to get implemented?