views:

1031

answers:

5

When Mac OS X goes to sleep, due to closing a laptop or selecting "Sleep" from the Apple menu, how does it suspend an executing process?

I suppose non-windowed processes are simply suspended at an arbitrary point of execution. Is that also true for Cocoa apps, or does the OS wait until control returns to the run loop dispatcher, and goes to sleep in a "known" location? Does any modern OS do that, or is it usually safe enough to simply suspend an app no matter what it is doing?

I'm curious, because allowing sleep to occur at any moment means, from the app's perspective, the system clock could suddenly leap forward by a significant amount. That's a possibility I don't usually consider while coding.

+1  A: 

I believe it will just suspend all apps wherever they happen to be.

Remember, this happens all the time anyway. Applications are constantly suspended and resumed due to context switching. So, really, the clock could jump between any 2 instructions in your app, though usually not in a noticable/significant way.

If the OS waited for the app to return to some main loop you could run into situations where applications cause the sleep to hang. If they're doing a lot of work and not returning to the run loop dispatcher they would prevent the machine from going to sleep. That wouldn't be very good. :)

Herms
But it wouldn't be unprecedented for the OS to request that the app suspends itself, then forces it if it doesn't in a specified amount of time. So good citizens are allowed to clean up and bad citizens aren't allowed to make trouble.
benzado
A: 

And if you set the time it also appears to leap forward to the running programs. Nothing special either.

Lars Truijens
+2  A: 

It depends on your app.
If you are interacting with external systems (think networking or doing something over usb/firewire,etc) then it might be affected. An application running on OSX gets to run for a limited time ( max 10ms ) , after which it is interrupted by the kernel which schedules a new process from the process queue to run on the CPU. This is transparent for the application , which "thinks" that it runs all the time on the CPU. Thus , a transition to sleep is no different - apart from the time jumping ahead.
If you need to be aware that there was a transition to sleep mode please refer to this tech note which details how to receive notifications about the state change : Registering and unregistering for sleep and wake notifications

cavver
A: 

Check out this Wikipedia article. Cavver is correct in stating that things like network connections may time out, and thus those services may be interrupted.

Milhous
+9  A: 

Your app is interrupted exactly where it is that moment if the CPU is actually currently executing code of your app. Your app constantly gets execution time by the task scheduler, that decides which app gets CPU time, on which core, and for how long. Once the system really goes to sleep, the scheduler simply gives no time to your app any longer, thus it will stop execution wherever it is at that moment, which can happen pretty much everywhere. However, the kernel must be in a clean state. That means if you just made a call into the kernel (many libC functions do) and this call is not at some safe-point (e.g. sleeping, waiting for a condition to become true, etc.) or possible holding critical kernel locks (e.g. funnels), the kernel may suspend sleep till this call returns back to user space or execution reaches such a safe-point before it finally cancels your app from the task scheduler.

You can open a kernel port and register for sleep/wake-up events. In that case, your app will receive an event, when the system wants to go to sleep. You have several possibilities. One is to reply to it, that the system may progress. Another one is to suspend sleep; however, Apple says certain events can be suspended at most 30 seconds, after that, the system will just continue, whether your app likes or not. And finally, you can cancel it; though not all events can be canceled. If the system already decided it will go to sleep, you can only suspend this by at most 30 seconds or allow it at once, you cannot cancel it. However, you can also listen to an event, where the system asks apps, if it is okay to go to sleep now and there you can reply "no", causing a sleep to be canceled.

The difference between "Is it okay to sleep" and "I'm planing on going to sleep" is: The first one is sent if the power saving settings are applied, that is, if the user has not moved the mouse or typed anything for the time configured there. In that case the system will just ask, if sleep is okay. An app like Apple's DVD Player will say "no", because most likely the user watches a DVD and thus doesn't interact with the computer, still no reason to go to sleep. OTOH, if the user closes his Mac Book, apps are not asked, the system will go to sleep for sure and just informs apps, that have now up to 30 seconds to react to it.

Wake-up events can also be quite interesting to catch. E.g. if your system wakes up, open files might be inaccessible (an external drive has been unplugged) or network sockets won't work any longer (network has changed). So you may re-init certain app parts before using them and running into errors that are more or less expected.

Apple's page regarding catching these events.

Mecki