shutdown function now blocks until worker threads have consumed all events on the queue