Potential Deadlock

Potential Deadlock

Old forum URL: forums.lhotka.net/forums/t/2472.aspx


Jason Gerard posted on Friday, March 02, 2007

    I did a cursory search of the forums and I didn't see this brought up anywhere.

I've never used CSLA before but I picked up the Expert C# book and I was browsing through the CS source for version 2.1.4 and I saw this in the ctor of the BusinessBase class.

lock (this.GetType())
{
// blah
}

Locking on a Type can lead to deadlocks since there is only one Type object loaded per app. While you could get away with this if the type your were locking on isn't public and you know for sure no other code is locking on it, that's obviously not the case in this constructor. Also, calling a method to get the type is not as performant as having a local object to lock on.

The recommended and safer approach is to create a private class level "lock" object to use for locking in that class.

private object _myLock = new object();
...
lock(_myLock)
{
//blah
}

RockfordLhotka replied on Saturday, March 03, 2007

That is a good observation. However, in this case the resource being protected by the lock is a static resource, and so the lock must occur at the AppDomain level.

Arguably I could have done this:

private static object _myLock = new object();
...
lock(_myLock)
{
//blah
}

To be slightly more "proper", but the net result is the same as far as I can see.

RockfordLhotka replied on Saturday, March 03, 2007

Having had my morning cup of coffee, the fact is that you can't even use a static field like I said in my previous post, because that would span all instances of any subclass of BusinessBase - which is bad.

What's needed is some per-instance-type object against which the code can lock. The use of this.GetType() is an easy way to get exactly such an object.

But if you can think of a better way to get an object that is common only to all instances of a specific subclass of BusinessBase, then I'm totally open to using such a technique.

Something like a Dictionary<type,object> came to mind - but then there are threading (and overhead) issues with creating/populating/maintaining that Dictionary - so it seems like a very problematic approach.

Also, remember that this lock process occurs only on the very first time the first isntance of a given business object type is created. So anything (like a Dictionary) that involves consuming memory over the lifetime of the AppDomain is a bad solution - because that memory would be wasted - no code would ever access the value after that one, first hit.

Maybe, just maybe, something like this would work. In BusinessBase:

protected abstract object GetSyncRoot();

Then in every subclass you'd have to implement that method like this:

private static object _syncRoot = new object();

protected override object GetSyncRoot()
{
  return _syncRoot;
}

Of course this would instantly break every object in every application where CSLA is used, and so it is a very poor solution too...

Jason Gerard replied on Monday, March 05, 2007

You could define GetSyncRoot() in the base like so

protected virtual object GetSyncRoot()
{
  return this.GetType();
}

and update the Constructor to use it.

Then specify in the book, comments, everywhere that you should override with with an instance type lock.

Seems a bit of a hack though that would never get overriden.

RockfordLhotka replied on Thursday, March 08, 2007

Yes, that would work. But I agree that it would likely never been overridden, so I think I won’t change anything at this point.

 

If someone comes along with an actual deadlock issue that requires a solution, I may make such a change at that time.

 

Rocky

 

From: Jason Gerard [mailto:cslanet@lhotka.net]
Sent: Monday, March 05, 2007 10:08 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Potential Deadlock

 

You could define GetSyncRoot() in the base like so

protected virtual object GetSyncRoot()
{
  return this.GetType();
}

and update the Constructor to use it.

Then specify in the book, comments, everywhere that you should override with with an instance type lock.

Seems a bit of a hack though that would never get overriden.


antoan replied on Wednesday, March 14, 2007

Pardon my ignorance but can someone explain why it is nessesary to do a lock on the type. What scenario could pose a problem if the type were not locked that way?

RockfordLhotka replied on Wednesday, March 14, 2007

I discuss this briefly in the CSLA .NET Version 2.1 Handbook as well, but the short of it is that the first time an object of any given type is created, its validation and authorization rules are added to a static/Shared list.

If the first creation of that type happened in two objects of the same type at the same time on different threads in the same AppDomain, then you could end up with both objects adding the same information to the same static/Shared lists. The result would be double entries at best, a crash at worst.

The locking is used to avoid that scenario.

Copyright (c) Marimer LLC