Skip to content
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

Serious concerns about thread safety #38

Closed
ivankoster opened this issue Dec 10, 2018 · 7 comments
Closed

Serious concerns about thread safety #38

ivankoster opened this issue Dec 10, 2018 · 7 comments
Labels

Comments

@ivankoster
Copy link

Hello,

I was interested using this cache and started reading the code to understand it.
I pretty quickly identified a scenario that is probably not threadsafe.
In the class Index<TKey, T>, method GetItem(..)

if ((node?.Value == null) && (creator != null))
{
    ...
}

return node?.Value;

When the method RemoveFromCache() from class Node finishes between the if and return statement in the above snippet, null will be returned from this GetItem() method, because there are no read locks here. I don't think that is the intended behavior?

Also, the remarks for the class FluidCache says there are 2 locks, but I can easily spot 4, in:

  • FluidCache
  • Index
  • LifespanManager
  • Node
@dennisdoomen
Copy link
Owner

Thanks for reporting it. I'll need to dive into it to see if you're right.

@dennisdoomen
Copy link
Owner

You mean that the node created in GetItem gets removed by RemoveFromCache before GetItem returns?

@ivankoster
Copy link
Author

The expression node?.Value occurs twice in the snippet I copy pasted.
If the first expression node?.Value returns non-null, because its in the cache, you advance to below the if statement.
Then another thread that is in RemoveFromCache can invalidate the node.
Then the original thread in GetItem() does the 2nd evaluation of node?.Value.
This time it returns null.

@dennisdoomen
Copy link
Owner

dennisdoomen commented Dec 18, 2018

You're right. The documentation is inconsistent because the concrete GetItem method documents it can return null, but the interface doesn't say that.

@dennisdoomen
Copy link
Owner

@ivankoster in your opinion, would you expect GetItem to ever return a null under high load?

@ivankoster
Copy link
Author

I would expect it to never return null. That would make it consistent with the Base Class Library, for example ConcurrentDictionary.GetOrAdd

@dennisdoomen
Copy link
Owner

Yeah, I agree. I need to carefully analyze that situation so to not cause any deadlocks (again).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants