More efficient synchronization

Use atomic ops on the state variable. This lets new requests go ahead even when
something has the main lock, and lets us simplify that lock to a normal Mutex
instead of an RWMutex.