Handle some tricky Comm lifecycle issues

* If the comm was a primary comm, but there was an error opening it, _closed was False, which is wrong
* If Comm.close() was called, but an error happened, it still appeared to be open

This change makes the _closed attribute more conservative.  If _closed is False, the comm is definitely open for messages.  If _closed is True, we either didn't initialize correctly, or we tried to close at some point.