Fix an issue causing lock contention in ObtainProxyType #60
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
It seems there is a misconception in how the ReaderWriterLockSlim works in regards to Upgradeable Read Locks.
MSDN: "Only one thread can enter upgradeable mode at any given time. If a thread is in upgradeable mode, and there are no threads waiting to enter write mode, any number of other threads can enter read mode, even if there are threads waiting to enter upgradeable mode."
-- http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.enterupgradeablereadlock.aspx
This change avoids taking an upgradeable read lock for as long as possible, then serializes the execution (as the upgradeable read lock is acquired) but still lets other threads get read locks and potentially get cache hits while the new proxy type is generated. Only in the last moment (soon before the write to the cache) we upgrade to a write lock. This will drain the read locks and take the write lock, write the change to the cache and then release the lock. Other threads stuck on acquiring the read lock will continue, hitting the cache, and the threads waiting to acquire the upgradeable read lock will one by one get a cache hit or a cache miss followed by an upgrade and cache population.