Seperated out mutexes for each resource

This breaks apart mutex usage for each resource that we are
locking. This creates a `Queue` and `Waiting` class that manage
their own mutexes. The final resource is the collection of
spawned workers, which the `WorkerPool` has a mutex for. This is
clearer about the intent of what resource we are locking and
waiting for.