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. This also prevents duplicate parsing.
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.`
Fixes#47
This disallows reparsing, but since that can be a significant source
of errors I think this is actually beneficial.
This also refactors to avoid storing the TypeId, though that is less
of a gain.
The client Request now uses the same system as a server Response to track
the write status of headers, and the API has been updated accordingly.
Additionally, the Request constructors have been moved onto the Request object
instead of being top-level hyper functions, as this better namespaces the
client and Server.
Trying to default the type parameters leads to an ICE and strange type errors.
I think this is just due to the experimental state of default type params and
this change can be rolled back when they are fixed.
Expose Server::many for creating a Server that will listen on many (ip, port)
pairs.
Handler still receives a simple Iterator of (Request, Response) pairs.
This is a breaking change since it changes the representation of Listener,
but Handler and Server::http are unchanged in their API.
Fixes#7
The client benchmarks did not have to be changed at all for this whole
refactor, and the server benchmark only had to specify a single type parameter,
and only because it writes out the type of Listener, which is not normal
usage.