Export to GitHub

linfu - issue #45

NullReferenceException


Posted on Jan 20, 2011 by Massive Rabbit

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.&lt;Initialize&gt;b__0(HashableWeakReference w) at System.Collections.Generic.HashSet1.RemoveWhere(Predicate1 match) at LinFu.IoC.Configuration.Initializer1.Initialize(IInitialize1 target, T source) at LinFu.IoC.Configuration.Initializer1.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.MemberResolver1.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.BaseFactory1.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 Bird

Actually, 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 Rabbit

Wow, that's a quick react, thx a lot !

Have a nice day :-)

Status: Fixed

Labels:
Type-Defect Priority-Medium