A customer discovered that their application’s shutdown code sometimes deadlocked. To address the problem, they moved the bulk of their shutdown code to the WM_ENDSESSION
message handler. The customer found my earlier discussion of the WM_ENDSESSION
message and wondered if they were doing the right thing.
Yes, it’s okay to do shutdown activities in response to the WM_ENDSESSION
message, provided that the wParam
is nonzero, indicating that the session really is ending. If the wParam
is zero, then it means that the session is not ending, so you had better not destroy anything you still need.
Recall the shutdown sequence: First, the application receives a WM_QUERYENDSESSION
message. Here is the traditional point at which you can display a prompt to ask the user whether they want to save their unsaved changes.¹ Normally, you return TRUE
, but if the user hits Cancel or otherwise indicates that they don’t want to shut down after all, then you return FALSE
.
If you returned TRUE
, then you will eventually receive a WM_ENDSESSION
message whose wParam
indicates whether the session really is ending. (The session might not actually be ending if another application returned FALSE
to the WM_QUERYENDSESSION
message, or if the user canceled shutdown from the UI.)
The customer shared some of their code, and I noticed that they were destroying a window in their WM_ENDSESSION
message handler, which is suspicious for two reasons:
- If the
wParam
isFALSE
, the application will continue to run, but it lost one of its windows! - If the
wParam
isTRUE
, then it’s okay to destroy things, but remember that you are running under a time constraint, and the building is being demolished, so you probably shouldn’t be wasting time sweeping the floor and emptying the trash cans.
What you could do is to kick off a background thread to prepare for shutdown when you receive the WM_QUERYENDSESSION
message. For example, you might start an autosave operation. Whatever you do, make sure that it’s okay for the operation to occur even if the shutdown is subsequently canceled.
When you get the WM_ENDSESSION
message, you wait until that background operation completes before telling the system, “I’m good; you can shut down now.”
Opportunistically starting the operation when you get the WM_QUERYENDSESSION
message means that you can respond more quickly to the WM_ENDSESSION
message.
¹ In practice, displaying a prompt is usually not a good idea because if you don’t respond to the message after a few seconds, the system will shut down without you.
0 comments