The &xshutdown; feature has cost me a lot of thought, because it is really not documented
anywhere what happens during the normal shutdown process.
&os2; per default knows two different shutdown APIs:
- DosShutdown only closes all open files, flushes
all file-system buffers und unmounts all file systems; this is what happens
after pressing Ctrl-Alt-Del. No applications are properly closed, and the WPS
is not saved.
- WinShutdownSystem however is the Presentation Manager API
which closes
all windows, saves the WPS and finally calls DosShutdown.
Just the regular shutdown procedure that you are used to: this is executed when you
select "Shutdown" from the Desktop's context menu or the respective icons from the
Launchpad or &warpcenter;.
Trouble is, there is no function "in between" these two. If you call
DosShutdown the WPS data is not saved. And if you call
WinShutdownSystem
you get the regular shutdown without any further chance to interfere. So basically, I
had to recode a complete new WinShutdownSystem,
which will now be explained. This was quite difficult, since IBM hardly explains
anything about what is really going on during WinShutdownSystem.
Note: In &xwp;, the "eXtended Shutdown" and
"Restart Desktop" routines share the same code; they
only differ in what happens after all windows have been closed. I will thus use the term
"&xshutdown;" in the following explanations for both features, unless otherwise stated.
&xshutdown; is integrated into the WPS
and relies heavily on the &xwp; class replacements.
I have intentionally not put the &xshutdown; code into a separate .EXE file for
two reasons: for one, &xshutdown; needs access to WPS internal data, which is
only available from the SOM context; second, I want to prevent people from
trying to use &xshutdown; separately, without having the
&xwp; classes installed, because this could severely damage the Workplace Shell.
In more detail, &xshutdown; relies on the XFldObject replacement class and the &xwp; Worker
thread, which cooperatively keep track of the WPS internal data.
To understand what &xshutdown; is now doing, it is necessary to understand how the
WPS handles its objects internally. Every single
object which becomes relevant to the WPS at some point, be it through populating a folder or
querying its settings or starting a program or whatever, is -- in WPS terminology --
"awakened" by the system, which means that it exists as a SOM object in memory.
The WPS only very rarely puts awake objects back to sleep though,
which would free the associated memory and store the object's data back to disk.
This has two consequences:
- There are always many more awakened objects on your system than
you would actually think, because most of them aren't currently visible.
Even after you close an open folder, the objects therein remain awake; this
speeds up populating the folder when it's opened a second time.
As a result however, the WPS eats up more and more of your memory with each
folder you open.
(If you have turned on the &xshutdown; log file, you can see how many awake objects
were saved by &xshutdown;; these are usually several hundred objects, even though
&xshutdown; doesn't save all awake objects, but only descendants of WPFolder and WPAbstract.
On the "Internals" page in the Desktop's settings notebook you can take a look at how
many objects are currently awake.)
- A change to the object's data sometimes has only an
effect on the SOM object in memory, but is not always saved to disk
or the OS2.INI / OS2SYS.INI files. This is why sometimes the WPS gets into
trouble if you make comprehensive changes, such as
moving a folder containing many abstract objects, and do not shutdown properly:
the physical file data on disk and the WPS records differ then.
This is what &xshutdown; needs the XFldObject class for, which
replaces WPObject.
Every time an object is awakened,
the WPS calls several methods (among them wpInitData and
wpObjectReady).
XFldObject overrides these and passes the object address in memory
to the Worker thread, which will then
properly update an &xwp;-internal list of all currently awake objects.
As far as I know, there
is no other way to find out which objects are currently awake; at least
there is no documented API for enumerating them.
Now, when &xshutdown; is initiated and confirmed, it first starts
two new threads for the following shutdown procedure,
which run parallel to the regular WPS threads: the main "Shutdown thread"
with the message queue for
the status window, and the "Update thread",
which monitors the &os2; Window List and posts messages to the main shutdown thread,
if the status window needs to be updated.
So closing all currently open windows is a fairly complex
process of interaction between these two threads:
the Shutdown thread closes a window and then
goes to sleep until the Update thread has detected a change in the Window List
(which means that
the window has successfully been closed) and posts a message back to the Shutdown thread,
which then in turn closes
the next window, until all windows are closed.
When all windows are closed, the Update thread exits.
Now the Shutdown thread goes through the
list of currently awake objects (which was described above)
and forces saving their data to the
INI files or to disk by calling each object's wpSaveImmediate
method. This is only done for WPAbstract and WPFolder descendants, because from
my experience, all other classes save their data synchroneously. (I have tried saving
all WPFileSystem descendants once, and this caused a lot of extended attributes to be
created for every single file that was ever awakened by the WPS.
In addition, shutdown took ages then.)
Finally, depending on what action was desired, the Shutdown thread does one of the
following:
- If you selected "Restart Desktop", the Shutdown thread
simply executes DosExit(EXIT_PROCESS, 0). Since &xwp; is part of
the Workplace process, and all parts of the WPS are running in this one process
(the second instance of PMSHELL.EXE),
this will terminate the whole Workplace Shell. The Shell process
(the first instance of PMSHELL.EXE) will then restart the WPS
automatically.
- If you selected "Shutdown" and "Reboot afterwards",
&xshutdown; now also saves the INI files
to disk. This is necessary, because DosShutdown,
which is called afterwards, does not save them either.
(I guess it's because the INI file API's belong to Presentation Manager.)
Since the PM INI file API's prohibit simply closing the user and system profiles
(which does write their data to disk for all other profiles), &xwp; copies them
to two temporary profiles, deletes the originals, and then renames the temporary
profiles to the names of the originals.
After DosShutdown
("Releasing file systems..."), the system is rebooted via a call
to the DOS.SYS device driver.
This feature is documented in EDM/2 volume 5, issue 9.
- If you selected "Shutdown" and NOT "Reboot afterwards",
after DosShutdown, &xshutdown; disables the window list and then
simply blocks the system by calling DosEnterCritSec
and staying in an infinite loop. Since all file systems are closed, no further
action should
be possible, except for turning off your computer or pressing Ctrl-Alt-Del.