Reactor loop fixes

We discovered that puma consumed all available disk in one of our instances. It turns out that the problem was repeated logging due to unconditionally retrying the reactor loop, while the teardown for `run` would ensure that subsequent runs would immediately fail.

The below pull request addresses this issue by only closing the socket after the server thread has finished executing. This pull request also addresses the cause of the failure. Namely, the reactor loop tried to select on a closed socket, which results in an IOError.

There is still a big problem with uncaught exceptions in the run-loop, as the current set of open sockets will be forgotten (and possibly never closed). However, I can't see how that can be accomplished without a significant reactor rewrite.