The boost documentation for upgradable and shared locks says that when shared locks are held only one other thread may acquire an upgradable lock. So that if other threads try to acquire an upgradable lock when shared lock(s) are held along with the upgradable lock they will block.
Is there some deadlock possibility that I am missing when more than one thread acquire upgradable locks along with one (or more than one shared lock)? Or is this just a logical requirement (so a "should not do this" sort of thing)?
Note that I am not talking about exclusively locked states. Only an upgradeable locked state. If an upgradable lock is held along with other shared locks it is in essence a READ lock. Then why can't two upgradable locks be held together?
The two types are exclusive and shared locks. Exclusive locks can be active or retained; shared locks can only be active (see Active and retained states for locks ).
When a statement reads data without making any modifications, its transaction obtains a shared lock on the data. Another transaction that tries to read the same data is permitted to read, but a transaction that tries to update the data will be prevented from doing so until the shared lock is released.
When a statement modifies data, its transaction holds an exclusive lock on data that prevents other transactions from accessing the data. This lock remains in place until the transaction holding the lock issues a commit or rollback.
Is there some deadlock possibility that I am missing when more than one thread acquire upgradable locks
TL;DR Yes, there is.
along with one (or more than one shared lock)
This doesn't really affect the deadlock possibility. Allowing shared locks while upgradeable lock exists is simply a feature of upgradeable locks, compared to an exclusive lock.
Let us first consider what upgradeable locks can be used for. We shall imagine the following situation:
Now, let us consider that we only have reader (shared) / writer (exclusive) locks, with no upgradeable lock:
It may be considered a disadvantage that the read portion of the check - write cycle blocks even reading threads. So, let us consider an alternative:
Between 3. and 4. more than one writer may have finished checking the state - since they can check concurrently - and are now racing to take the exclusive lock. Only one can win, and others must block. While they are blocking, the winner is modifying the state.
In this situation, the writers waiting to grab the exclusive lock can not assume that the condition that they checked is valid any more! Another writer may have grabbed the lock before them, and the state has now been modified. They could ignore this, which might lead to undefined behaviour, depending on what the relation with the condition and the modification is. Or, they could check the condition again when they get the exclusive lock, which reverts us back to the first approach, except with potentially redundant checks that were useless because of the race. Either way, this approach is worse than the first one.
A solution for the situation above is the privileged read (upgradeable) lock:
Let us consider a situation where multiple writers have been granted a privileged lock. They get to check the expensive condition concurrently, which is nice, but they still have a race to upgrade the lock. This time, the race results in a dead lock, because each writer hold the read lock, and wait for all read locks to be released before they can upgrade.
If the upgradeable lock is exclusive in relation to other upgradeable locks, then this dead lock cannot occur, and the race doesn't exist between the expensive check and the modification, but reader threads may still operate while the writer is checking.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With