[ https://issues.apache.org/jira/browse/LOG4NET-646?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Davyd McColl reassigned LOG4NET-646: ------------------------------------ Assignee: Davyd McColl > RendererMap not threadsafe (IndexOutOfRangeException) > ----------------------------------------------------- > > Key: LOG4NET-646 > URL: https://issues.apache.org/jira/browse/LOG4NET-646 > Project: Log4net > Issue Type: Bug > Components: Core > Affects Versions: 2.0.8 > Reporter: Matt Grimwade > Assignee: Davyd McColl > Priority: Critical > > Concurrent calls to code such as > {code} > loggerRepository.RendererMap.FindAndRender(new { Foo = "bar" }); > {code} > occasionally fail with > {code} > System.IndexOutOfRangeException: Index was outside the bounds of the array. > at System.Collections.Hashtable.Insert(Object key, Object nvalue, Boolean > add) > at log4net.ObjectRenderer.RendererMap.Get(Type type) > at log4net.ObjectRenderer.RendererMap.FindAndRender(Object obj, > TextWriter writer) > {code} > Once this has occured, further calls to RendererMap throw. This causes total > failure of the logging system. > This appears to be because log4net.ObjectRenderer.RendererMap is not > thread-safe. Internally it holds two Hashtables, {{m_map}} and {{m_cache}}. > The first uses a synchronized wrapper and the second does not. > From > https://docs.microsoft.com/en-us/dotnet/api/system.collections.hashtable?view=netframework-4.8: > {quote} > Hashtable is thread safe for use by multiple reader threads and a single > writing thread. It is thread safe for multi-thread use when only one of the > threads perform write (update) operations, which allows for lock-free reads > provided that the writers are serialized to the Hashtable. To support > multiple writers all operations on the Hashtable must be done through the > wrapper returned by the Synchronized(Hashtable) method, provided that there > are no threads reading the Hashtable object. > {quote} > So when two threads attempt to mutate the cache concurrently its internal > state is corrupted. > A solution (at least for .NET Framework 4.0 onwards) might be to replace both > with a ConcurrentDictionary<Type, IObjectRenderer> accessed via its GetOrAdd > method. -- This message was sent by Atlassian Jira (v8.3.4#803005)