[
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)