ToUserDevice: synchronize file_operations vs. cleanup

Previously, dev_read, dev_write, and dev_poll were only loosely synchronized
with ToUserDevice::cleanup.  While that method attempts to clear out the
read workqueue, it is racy since dev_{read,write,poll} might have already
checked GETELEM but not yet added itself to the workqueue.  In this case,
cleanup will finish and ~ToUserDevice can run while dev_X still holds a
pointer to the now-dead object.

Cliff Frey actually mentioned that he was worried about this bug in eb2b54e
way back in May of 2011, although it is not necessary to block cleanup until
dev_release.

This change adds a global spinlock that controls access to elem_map as well
as an atomic member, _use_count, that indicates whether some userland
process is in the middle of an operation that expects elem to remain valid.
This counter is only incremented under the global lock and, assuming elem
was valid, the utility template ref_holder automatically decrements the
use_count once we leave scope.  Additionally, cleanup waits takes the global
lock to clear the elem_map entry and waits until _use_count is zero before
moving on.  This ensures that elem is valid throughout a call to dev_X.

It would probably be worth adding several more assertions about the state of
elem_map at different points in the code, but that is a commit for the
Mysterious Future.

I felt a little strange using typeof.  After checking the rest of the
codebase, there are plenty of other places that do too.