Coder Social home page Coder Social logo

inmemcached's People

Contributors

pvginkel avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar

inmemcached's Issues

Potential race condition in Free calls between Remove and Dispose

I'm trying to review the code to try to ensure that there are no gremlins hiding in the multi-threaded complexity.. and I'm finding it quite difficult! Let me know if any of what I've written here seems incorrect..

In the "Add" method, you're not locking the handle when the _cache.TryAdd call fails since no other threads are able to get a reference to that handle and so there will never be multiple threads trying to manipulate it. This is unlike in "Get" and "Remove" where locking is required because it's possible for one thread to enter the "_cache.TryGetValue" in "Get" condition and for another to enter the "_cache.TryRemove" condition in "Remove" simultaneously; in this case, only one of these operations may be allowed at a time (and if "Remove" gets there first then "Get" will have to return null since the handle has been free'd, which is why "ToByteArray" may return null).

I presume that you're applying similar logic to the lock in the "Dispose" method. However, if that is the case then there is a potential race condition. The "Values" property on the ConcurrentDictionary is a snapshot of Values that are present at the point at which the property is accessed. If any values are removed from the dictionary during the enumeration, this will not affect the values that are enumerated over. For example, if there are three handles to enumerate over and the third handle is removed by a "Remove" call on a thread that executes while another thread is already enumerating the dictionary values from within "Dispose" then "Dispose" will try to Free the handle that "Remove" has already free'd.

This is illustrated with the below example:

class Program
{
    static void Main(string[] args)
    {
        var cache = new ConcurrentDictionary<int, MemoryHandle>();
        cache.TryAdd(1, new MemoryHandle());
        new Thread(() =>
        {
            foreach (var value in cache.Values)
            {
                // Introduce a short delay to ensure that the TryRemove call below completes
                // before this enumeration completes
                Thread.Sleep(TimeSpan.FromSeconds(1));
                value.Free();
            }
        }).Start();
        new Thread(() =>
        {
            MemoryHandle removedHandle;
            if (cache.TryRemove(1, out removedHandle))
                removedHandle.Free();
        }).Start();
        Console.ReadLine();
    }

    private sealed class MemoryHandle
    {
        private bool _freed = false;
        public void Free()
        {
            if (_freed)
                throw new Exception("This handle has already been free'd!");
            _freed = true;
        }
    }
}

Maybe it would be best to change "Free" to work like "ToByteArray" - in that it will perform no work if the handle is a null pointer?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.