hyperium/hyper — pull request #48 by reem (2014-09-20 11:17:10+00:00)
Title: Store Header Items behind an RWLock

This removes the need to receive `&mut self` in `get_ref` and `get.`

Since the interior mutability of the RWLock is needed only once, it is safe
to change the lifetime of the pointer given by read locks as by then all
mutation has been done.

Since `set` still requires `&mut self` there is no way to use the interior
mutability of the RWLock to modify an existing `&`-reference. However, the
use of interior mutability in `get_ref` means that `get_raw` is now
actually an unsafe operation because the (now `*const`) pointer could be
invalidated by a subsequent call to `get_ref.`

Commit 2ed2cd0 also fixed a possible race condition in this new scheme and
prevents duplicate parsing. From the commit message:

If two threads attempted to `get_ref` the same Header under two
representations, then it was possible that the second thread would
overwrite the work of the first thread, causing the first thread to do an
unchecked downcast to the wrong type.

In the case where they were the same Header representation, then the only
damage would be that it would be parsed twice and would possibly return a
false negative in one thread.

The new code checks that it was not a queued lock and will not override the
work of another thread, but will accept it if the other thread parsed the
header as the same type, thus also preventing duplicate parsing.

Commit 4b901ae also adds new tests for double-reads of the same header
and reads of two different headers as a sanity check that no deadlocks
were created in this refactor.