The standard library RwLock checks if it's panicking while making the
guard. This check needs to use a thread local key, which it lazily
creates. This causes reentrant/recursive locking, which leads to a
deadlock.
This commit replaces the std RwLock with one from spin, which does not
need to check thread local storage to lock. It's a spin-lock, but it is
configured to yield the thread on every unsuccessful spin. Also, the
lock can be created statically, which means we don't need once_cell.
An alternative to spin is parking_lot, but that has some compile errors
(it wants condvars to support monotonic clocks) and brings in more
dependencies.