Nicolás Sabena
unread,Jun 27, 2011, 1:52:50 PM6/27/11Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to Castle Project Development List
Hi. I think I found a little bug in the PerWebRequestLifestyleManager
that causes it not to release certain components (or releasing them
earlier than expected) when many requests end at the same time for
components of the same type (same instance of LifestyleManager).
This happens in the 2.5.3 release. The code in the main branch changed
substancially and this probably got fixed, but this bug may cause
leaks for people using this last release.
The problem is with the way the manager handles the internal Evict()
method:
internal void Evict(object instance)
{
using (new EvictionScope(this))
{
// that's not really thread safe, should we care
about it?
Kernel.ReleaseComponent(instance);
}
}
The commentary itself (from the actual code) signals the problem.
EvictionScope sets a class internal member, "evicting", to true while
in the scope, so that the Release() method does the actual release:
public override bool Release(object instance)
{
if (evicting == false) return false;
return base.Release(instance);
}
But since one PerWebRequestLifestyleManager is responsable for all
components of the same type, and "evicting" applies to the lifestyle
manager as a whole, it can happen that while one thread sets or clears
the EvictionScope, another thread expects another value, and an
instance misses the Release() (or get released early).
The solution seems to be locking the evict operation:
private object o = new object();
internal void Evict(object instance)
{
// lock so nobody else changes evicting while releasing.
lock (o)
{
using (new EvictionScope(this))
{
Kernel.ReleaseComponent(instance);
}
}
}
What do you think about this?
Thanks a lot,
Nicolás.