A NullReference exception occurs in a multithreaded environment while accessing GetService interface of LinFu v2.3.0.19319 concurrently.
The pb seems to occur because of the static variable _instance declared as an hashset that is not threadsafe and protected against concurrent accesses in file LinFu\src\LinFu.IoC\Configuration\InitializerOfT.cs:
public class Initializer<T> : IPostProcessor
{
private static readonly HashSet<IInitialize<T>> _instances = new HashSet<IInitialize<T>>();
private static void Initialize(IInitialize<T> target, T source)
{
if (target == null)
return;
// Make sure that the target is initialized only once
if (_instances.Contains(target)) <--- Exception !!
return;
// Initialize the target
target.Initialize(source);
_instances.Add(target);
}
}
Here is the call stack :
at LinFu.IoC.Configuration.Initializer1.<Initialize>b__0(HashableWeakReference w)
at System.Collections.Generic.HashSet
1.RemoveWhere(Predicate1 match)
at LinFu.IoC.Configuration.Initializer
1.Initialize(IInitialize1 target, T source)
at LinFu.IoC.Configuration.Initializer
1.PostProcess(IServiceRequestResult result)
at LinFu.IoC.CompositePostProcessor.PostProcess(IServiceRequestResult result)
at LinFu.IoC.DefaultGetServiceBehavior.GetService(IServiceRequest serviceRequest)
at LinFu.IoC.ServiceContainer.GetService(String serviceName, Type serviceType, Object[] additionalArguments)
at LinFu.IoC.ServiceContainer.GetService(Type serviceType, Object[] additionalArguments)
at LinFu.IoC.ContainerExtensions.GetService[T](IServiceContainer container, Object[] additionalArguments)
at LinFu.IoC.ContainerExtensions.<AddDefaultServices>b__5(IServiceContainer ioc)
at LinFu.IoC.Configuration.MemberResolver1.GetMethodFinder(IServiceContainer container)
at LinFu.IoC.Configuration.MemberResolver
1.ResolveFrom(Type concreteType, IServiceContainer container, IMethodFinderContext finderContext)
at LinFu.IoC.Configuration.DefaultActivator.CreateInstance(IContainerActivationContext context)
at LinFu.IoC.ContainerExtensions.AutoCreateInternal(IServiceContainer container, Type concreteType, Object[] additionalArguments)
at LinFu.IoC.Configuration.FactoryBuilder.<CreateFactoryMethodInternal>b__4[TService,TImplementation](IFactoryRequest request)
at LinFu.IoC.Factories.OncePerRequestFactory1.CreateInstance(IFactoryRequest request)
at LinFu.IoC.Factories.BaseFactory
1.LinFu.IoC.Interfaces.IFactory.CreateInstance(IFactoryRequest request)
at LinFu.IoC.DefaultCreator.CreateFrom(IFactoryRequest factoryRequest, IFactory factory)
at LinFu.IoC.DefaultGetServiceBehavior.GetService(IServiceRequest serviceRequest)
at LinFu.IoC.ServiceContainer.GetService(String serviceName, Type serviceType, Object[] additionalArguments)
at LinFu.IoC.ContainerExtensions.GetService(IServiceContainer container, IServiceInfo info, Object[] additionalArguments)
Comment #1
Posted on Jan 20, 2011 by Massive BirdActually, the NullReferenceException was caused by the following lines of code:
if ((_initializeCallCount = ++_initializeCallCount % 100) == 0) _instances.RemoveWhere(w => !w.IsAlive); // 'w' is sometimes null
I fixed it with the following patch:
if ((_initializeCallCount = ++_initializeCallCount % 100) == 0) _instances.RemoveWhere(w => w != null && !w.IsAlive);
Sorry for the inconvenience!
Comment #2
Posted on Jan 21, 2011 by Massive RabbitWow, that's a quick react, thx a lot !
Have a nice day :-)
Status: Fixed
Labels:
Type-Defect
Priority-Medium