Remove ThreadPool reliance on shared_ptr.

It didn't make sense in the context of the library, and the lifetime
management introduced more bugs than it solved.
Add ThreadPool destructor to avoid invalid state.

Specifically, waits for all threads to finish running and then
terminates them. This should probably be abstracted into a shutdown
policy, but for this simple use-case it works.

In any case, there is little reason to destroy the ThreadPool without
executing all tasks. Breaks contract.