bsimser / artemis-framework

Artemis is a high performance Entity System framework for games.
MIT License
2 stars 0 forks source link

Thread-safety issue in com.artemis.EntitySystem.SystemIndexManager #11

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Create multiple threads
2. in each thread create a World, add entities and systems
3. call world.process() a couple of times

What is the expected output? What do you see instead?
processEntities() in some EntitySystems is never called.

What version of the product are you using? On what operating system?
artemis-a609b2076aacc0ef5ecf0b390205d01bb88ceae2.jar, Windows 7 64bit

Here is the actual issue:

private static class SystemIndexManager {
    private static int INDEX = 0;
    private static final HashMap<Class<? extends EntitySystem>, Integer> indices = new HashMap<>();

    private static int getIndexFor(Class<? extends EntitySystem> es) {
        Integer index = indices.get(es);
        if (index == null) {
            index = INDEX++; // INDEX is static, accessed in ALL threads
            indices.put(es, index); // same issue here
        }
        return index;
    }
}

Solution:
Make one local SystemIndexManager object for each World instance, or simply 
something like this:

private static class SystemIndexManager {
    private static class Indices {
        public int INDEX = 0;
        public final HashMap<Class<? extends EntitySystem>, Integer> indices = new HashMap<>();
    }

    private static final ThreadLocal<Indices> threadLocalIndices = new ThreadLocal<Indices>() {
        @Override
        protected Indices initialValue() {
            return new Indices();
        }
    };

    private static int getIndexFor(Class<? extends EntitySystem> es) {
        Integer index = threadLocalIndices.get().indices.get(es);
        if (index == null) {
            index = threadLocalIndices.get().INDEX++;
            threadLocalIndices.get().indices.put(es, index);
        }
        return index;
    }
}

Original issue reported on code.google.com by art.kna...@googlemail.com on 28 Jul 2014 at 8:44