WASAPI prevents Windows automatic suspend? - c++

First time poster, be gentle ;-)
I'm writing an audio app (in C++) which runs as a Windows service, uses WASAPI to take samples from the line in jack, and does some processing on it.
Something I've noticed is that when my app is "recording", Windows won't automatically suspend or hibernate.
I've registered for power event notifications and, if I push the suspend button myself, my service gets the appropriate power events and handles them ok. If I leave the system to suspend on its own, the power events are never received.
If I remove the bits of code where I reference WASAPI, the power events are received as normal on both manual and automatic suspend. So it seems like there's something about using WASAPI that tells Windows to ignore the automatic suspend timer.
Can anyone help explain this behavior, and is there anything I can do to stop it? I don't want my app to be one of those which misbehaves and prevents systems from suspending..

Unfortuantely there's no mechanism to do what you want - opening an audio stream prevents power state transitions as does opening a file up over the network and any one of a number of other things.
This is a function of the audio driver (portcls.sys) and not WASAPI and is not a new behavior for Vista - I believe that XP and Win2K had similar behaviors (although power state transitions are much more reliable on Vista than they were on XP and Win2K so users tend to depend on them more).
On Windows 7 you can use the "powercfg -requests" to find if any parts of the system are preventing a machine from entering sleep. More information on that can be found here

Many thanks to Larry for confirming this behaviour is by design and not me doing something silly.
To work around this issue I used the Win32 CallNtPowerInformation() API to retrieve the system idle timer:
SYSTEM_POWER_INFORMATION spi = {0};
NTSTATUS status = CallNtPowerInformation(SystemPowerInformation, NULL, 0,
&spi, sizeof(spi));
if (NT_SUCCESS(status) && (spi.TimeRemaining==0))
{
// should have gone to sleep
}
The spi.TimeRemaining member counts down (in seconds) from the time specified by the user in Control Panel e.g. "System standby after 1 hour", and gets reset whenever CPU usage (as a percentage) rises above spi.MaxIdlenessAllowed.
If spi.TimeRemaining ever reaches zero, the system should have gone to sleep, so I close all my WASAPI handles and let it do so.

I believe there's a function in the power management API which allows an app to tell the OS that it doesn't want the system to go into power save mode during some time (I think it's an on/off type function). If something in WASAPI is calling that method, there may be nothing you can do. This would make sense with the hardware button behavior, since the power management service isn't forced to honor the app request depending on how the power mode is activated.
As for work-around, I don't know. One thing I might try is to read the power save timeout information from the power management API, and then suspend recording if the system is nearing the power save threshold; I have no idea how hard that would be though. Good luck. :)

One thing I might try is to read the power save timeout information from the power management API, and then suspend recording if the system is nearing the power save threshold;
A good idea - but quite hard I think. The power save timeout should be readable using power management API, but you'd also need to know the current user input idle state, which is not readable from a Windows service.

Related

WINAPI: GetSystemPowerStatus update rate too slow

To access the Windows system's current power state (battery level, ac present etc.) from my C++ application, I'm currently using the following WinAPI function:
BOOL WINAPI GetSystemPowerStatus(_Out_ LPSYSTEM_POWER_STATUS lpSystemPowerStatus);
This works well but the results I get with this call are too "old". Maybe this is because Windows or the connected UPS do update these values not that often.
Does anyone know a workaround for this? Or does anyone have a different solution for polling the system's current power state which may deliver more recent results?
Edit: I need this information to inform/warn the user about the power situation (fullscreen app, no Windows shell) and to transfer my application/device into a safe state when the battery level of the UPS gets critical in case of an AC power failure.

How to flush the Windows Event Log to disk?

I have a Windows 7 embedded device which is frequently power cycled like this: a local application writes an entry to the Application event log and a few seconds later it commands the custom power supply to cycle power. A clean Windows shutdown cannot be done. After the device boots back up, I check the Windows event log and notice the last entry missing.
Is there some way to flush the Windows event log to disk so that I don't miss that last entry? The application is written in C++.
Thanks,
Adnan
You have a hardware problem so the best solution is to resolve it in hardware. But moving on.
Use BIOS to ensure computer always starts after a power cycle
You have a hardware tool to perform the reboot. Could you reconfigure that so that rather than doing a hard power cycle while the computer is running, you:
notify the hardware power cycle tool,
perform an orderly shutdown, then
power the computer on again using the hardware power switch?
There is usually a bios setting which allows you to specify the action after a power cycle, e.g.
Leave the computer off,
Turn it on,
Turn it on only if it was on when power was lost.
If you can do this, then you can still do an orderly shutdown and wait for that to complete before powering on again.
Software Solution: Turn off disk write caching
It's not exactly clear what is causing your issue, but the following seem relevant.
Most likely, this is a result of disk write caching either by the disc controller hardware, or by the operating system.
You may be able to turn this off through the Disk Management tool:
http://www.thewindowsclub.com/enable-disable-disk-write-caching-windows-7-8
Software Solution: Flush the disk programmatically
Alternatively, you may be able to flush the disk cache programmatically. This tool may help:
https://superuser.com/questions/833552/manually-flushing-write-cache-on-window
Or indeed with WMI and PowerShell:
https://technet.microsoft.com/en-us/library/dn454975.aspx

how do i prevent screen-savers and sleeps during my program execution?

In a c++ program run on Win7, is there a way to fake a mouse movement or something like that, just to keep the screen saver from starting and the system from going to sleep? I'm looking for the minimal approach and I prefer not to use .NET.
Thanks,
-nuun
Don't mess with the screensaver settings, use SetThreadExecutionState. This is the API for informing windows on the fact that your application is active:
Enables an application to inform the
system that it is in use, thereby
preventing the system from entering
sleep or turning off the display while
the application is running.
, and
Multimedia applications, such as video
players and presentation applications,
must use ES_DISPLAY_REQUIRED when they
display video for long periods of time
without user input
That's not a bad idea, any decent media player does it... Look for SystemParametersInfo(SPI_SETSCREENSAVEACTIVE ...) function in Win32 api, it should do the trick.
Before Windows starts screen-saver, it sends SC_SCREENSAVE notification in WM_SYSCOMMAND message to applications. If application wants to prevent screen-saver from starting, it should set "handled" flag to true and return zero during message processing. There is also SC_MONITORPOWER to prevent display from going to low power state.
https://learn.microsoft.com/en-us/windows/desktop/menurc/wm-syscommand

Running background services on a PocketPC

I've recently bought myself a new cellphone, running Windows Mobile 6.1 Professional. And of course I am currently looking into doing some coding for it, on a hobby basis. My plan is to have a service running as a DLL, loaded by Services.exe. This needs to gather som data, and do som processing at regular intervals (every 5-10 minutes).
Since I need to run this at regular intervals, it is a bit of a problem for me, that the system typically goes to sleep (suspend) after a short period of inactivity by the user.
I have been reading all the documentation I could find on MSDN, and MSDN blogs about this subject, and it seems to me, that there are three possible solutions to this problem:
Keep the system in an "Always On"-state, by calling SystemIdleTimerReset periodically. This seems a bit excessive, and is therefore out of the question.
Have the system periodically waken up with CeRunAppAtTime, and enter the unattended state, to do my processing.
Use the unattended state instead of going into a full suspend. This would be transparent to the user, but the system would never go into sleep.
The second approach seems to be preferred, however, this would require an executable to be called by the system on wake up, with the only task of notifying my service that it should commence processing. This seems a bit unnecessary and I would like to avoid this extra executable. I could of course move all my processing into this extra executable, but I would like to use some of the facilities provided when running as a service, and also not have a program pop up (even if its in the background) whenever processing starts.
At first glance, the third approach seems to have the same basic problem as the first. However, I have read on some of the MSDN blogs, that it might be possible to actually conserve battery consumption with this approach, instead of going in and out of suspend mode often (The arguments for this was that the nature of the WM platform is to have a very little battery consumption, when the system is idle. And that going in and out of suspend require quite a bit of processing).
So I guess my questions are as following:
Which approach would you recommend in my situation? With respect to keeping a minimum battery consumption, and a nice clean implementation.
In the case of approach number two, is it possible to eliminate the need for a notifying executable? Either through alternative API functions, or existing generic applications on the platform?
In the case of approach number three, do you know of any information/statistics relevant to the claim, that it is possible to extend the battery lifetime when using unattended mode over going into suspend. E.g. how often do you need to pull the system out of suspend, before unattended mode is to be preferred.
Implementation specific (bonus) question: Is it necessary to regularly call SystemIdleTimerReset to stay in unattended mode?
And finally, if you think I have prematurely eliminated approach number one, please tell me why.
Please include in your response whether you base your response on knowledge, or are merely guessing (the latter is also very welcome!).
Please leave a comment, if you think I need to clarify any parts of this question.
CERunAppAtTime is a much-misunderstood API (largely because of the terrible name). It doesn't have to run an app. It can simply set a named system event (see the description of the pwszAppName parameter in the MSDN docs). If you care to know when it has fired (to lat your app put the device to sleep again when it's done processing) simply have a worker thread that is doing a WaitForSingleObject on that same named event.
Unattended state is often used for devices that need to keep an app running continuously (like an MP3 player) but conserve power by shutting down the backlight (probably the single most power consuming subsystem).
Obviously unattended mode uses significantly more powr than suspend, becasue in suspend the only power draw is for RAM self-refresh. In unattended mode the processor is stuill powered and running (and several peripherals may be too - depends on how the OEM defined their unattended mode).
SystemIdleTimerReset simply prevents the power manager from putting the device into low-power mode due to inactivity. This mode, whether suspended, unattended, flight or other, is defined by the OEM. Use it sparingly because when your do it impacts the power consumption of the device. Doing it in unattended mode is especially problematic from a user perspective because they might think the device is off (it looks that way) but now their battery life has gone south.
I had a whole long post detailing how you shouldn't expect to be able to get acceptable battery life because WM is not designed to support what you're trying to do, but -- you could signal your service on wakeup, do your processing, then use the methods in this post to put the device back to sleep immediately. You should be able to keep the ratio of on-time-to-sleep-time very low this way -- but as you say, I'm only guessing.
See also:
Power-Efficient Apps (MSDN)
Power To The People (Developers 1, Developers 2, Devices)
Power-Efficient WM Apps (blog post)

Off screen rendering when laptop shuts screen down?

I have a lengthy number-crunching process which takes advantage of quite abit of OpenGL off-screen rendering. It all works well but when I leave it to work on its own while I go make a sandwich I would usually find that it crashed while I was away.
I was able to determine that the crash occurs very close to the moment The laptop I'm using decides to turn off the screen to conserve energy. The crash itself is well inside the NVIDIA dlls so there is no hope to know what's going on.
The obvious solution is to turn off the power management feature that turns the screen and video card off but I'm looking for something more user friendly.
Is there a way to do this programatically?
I know there's a SETI#home implementation which takes advantage of GPU processing. How does it keep the video card from going to sleep?
I'm not sure what OS you're on, but windows sends a message that it is about to enter a new power state. You can listen for that and then either start processing on the CPU or deny the request to enter a lower-power state.
For the benefit of Linux users encountering a similar issue, I thought I'd add that, you can obtain similar notifications and inhibit power state changes using the DBUS API. An example script in Python, taken from the link, to inhibit power state change:
#!/usr/bin/python
import dbus
import time
bus = dbus.Bus(dbus.Bus.TYPE_SESSION)
devobj = bus.get_object('org.freedesktop.PowerManagement',
'/org/freedesktop/PowerManagement')
dev = dbus.Interface (devobj, "org.freedesktop.PowerManagement.Inhibit")
cookie = dev.Inhibit('Nautilus', 'Copying files from /media/SANVOL')
time.sleep(10)
dev.UnInhibit(cookie)
According to MSDN, there is an API that allows an application to tell Windows that it is still working and that Windows should not go to sleep or turn off the display.
The function is called SetThreadExecutionState (MSDN). It works for me, using the flags ES_SYSTEM_REQUIRED and ES_CONTINUOUS.
Note, however, that using this function does not stop the screen saver from running, which might interfere with your OpenGL app if the screen saver also uses OpenGL (oder Direct3D).