John Siracusa's Mountain Lion review contained a snippet that made me stop and think:
In Mountain Lion, OS X no longer pays attention to disk activity when deciding if it's OK to put the system to sleep. Instead, Apple recommends that applications make what Apple calls "power assertions" as a way to tell the OS when they're doing some useful work that the system should stay awake for.
I had noticed that my Mac Pro was now actually deigning to fall asleep under Mountain Lion, something that had never happened under earlier OS releases. I guess there had always been some kind of disk activity ticking over on a regular basis before (yes, I'm looking in your direction Xcode).
How then, I wondered, would this affect Sandvox? We'd not written any power management-specific code until now, even though it's clearly undesirable to have your Mac fall asleep in the middle of publishing. It seems we'd been simply getting lucky: while figuring out what needs publishing, Sandvox hits the disk pretty frequently to hash files, and after that while uploading, disk access is still quite frequent for any files that are uploaded directly, or as autosave kicks in.
Under Mountain Lion, the rules of the game have changed it seems; time to adapt.
So I did a search for "power assertions os x" and frankly came up pretty blank. It seems Apple's documentation mostly consists of reproducing chunks of the header files. Not to worry, they're fairly easy to understand, so here for the benefit of future generations is a simple example:
Having written this, I have discovered two other bits of info on the subject:
- Cocoa Is My Girlfriend covered more-or-less this back in 2009, with “The Journey To Disabling Sleep With IOKit”
- Technote QA1340 demonstrates use of various power management-related APIs, albeit with a misplaced * in this one
Interestingly, both examples suggest that if the power assertion fails for some reason (I haven’t come across an example of why yet), the work itself doesn’t get done. I consider this a poor choice — I would far rather that the app still do the work and risk being interrupted, than give up in advance!
Update: I've created KSPowerAssertion, a simple Cocoa wrapper around the above code.