Implement clean shutdown.

Refactor application initialization such that clean shutdown is
possible, and implement clean shutdown support.  With these changes in
place, the application responds to e.g. SIGTERM by joining on all
service threads before exiting.