If two threads hold an upgrade lock, and then both of them try to upgrade:
-The first thread cannot upgrade to a unique lock until the second thread releases its upgrade lock.
-The second thread cannot upgrade to a unique lock until the first thread releases its upgrade lock.
Hence, deadlock.
There are two ways to do read/write locks with upgradeability. The more common method used by most other libraries is to make the upgrade a non-blocking tryUpgrade() method or similar. The approach used by boost::threads is, IMO, smarter, but more confusing at first.
Here is the key: An upgrade lock is *not* a special type of read lock that can be upgraded. Don't think of it that way. Instead, think of it as a special type of write lock that can allow simultaneous read locks.
To use boost::thread terminology, multiple upgrade_locks cannot be simultaneously taken on the same mutex; however, while a single upgrade_lock is taken, an arbitrary number of shared_locks can also still be taken on the same mutex.
So:
unique_lock: No other locks may be taken at the same time.
upgrade_lock: Other shared_locks may be taken at the same time, but no other upgrade locks.
shared_lock: Other shared_locks may be taken at the same time.
You need to keep this in mind when coding, and keep your upgrade_lock usage restricted to those places where you *really* need it.