-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Atomicity in the Release method #4
Comments
Erik, This maybe an even better solution |
The issue I'm pointing out doesn't have to do with the GetOrAdd factory. In fact, this library doesn't use that overload of GetOrAdd, so the Lazy implementation isn't even needed. The issue I'm describing is that the functionality of the Release method must be atomic. There's no way to do that with ConcurrentDictionary. I ended up taking this library as a base and reimplemented with a normal dictionary and an AsyncLock around the dictionary code in the Wait and Release methods. I also added a small IDisposable wrapper class as a return from the Wait methods, so you can use the locks in a |
Yes, I understand, and the information you stated above is correct, but I think the Microsoft faster team have a better solution as they are not doing any of that extra work that Darkseal kindly implemented. I just think the Microsoft solution I linked in issue 5 is more elegant and Darkseal can simplify the existing lock provider code using SafeConcurrentDictionary and have a simpler solution. I am just sharing some knowledge I found out recently. |
Hi @ErikPilsits-RJW , thanks for sharing your thoughts: I think that I can switch this library with your implementation as well. Do you mind to share it? Many thanks, |
This is what I ended up with. It requires Nito.AsyncEx.Coordination for the async lock.
|
I don't think that will work. The idea of the lock is to be multi-threaded, so there will be different threads calling the same idToLock. That's why there is a waiter counter. Also, the thread id doesn't hold up when you start dealing with async tasks. See here. |
I think you have an atomicity issue in the release method.
There is a chance that between checking
!semaphore.HasWaiters
and removing the dictionary entry, that another thread could callWait()
. You would know this after the removal if the semaphore suddenly has waiters. At that point you could try to add the semaphore back to the dictionary, but there's a chance that yet another thread has calledWait()
and created a new dictionary entry.The text was updated successfully, but these errors were encountered: