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.