Posts Tagged “d9”

Follow


ReaderWriterLockSlim vs lock

  

So you’ve got this boring old lock keyword, with its “only one at a time” semantics, and you think “hey, lets use the ReaderWriterLock, since its cooler, and it now has a Slim version so it MUST be great !”

 

That is wrong on many levels.

 

Lets start with exploring what the RWLS is about, in contrast to the lock keyword (which is a syntactic sugar for Monitor).

Both are used to synchronise access to a shared resource that might get read and written by different threads at the same time.

the general pattern is (pseudo-code, please do not Copy And Paste to your favourite IDE :) ):


variable aResource

lock aLock

 

// when reading from the shared resource

lock_for_read(aLock):

   foo = aResource.get_value

   do_something_with foo

 

// when writing to the shared resource

lock_for_write(aLock):

   aResource.set_value something

 

The Monitor construct only allow a single thread to access the synchronised block at a time, whether it is for reading or writing, so actually the isn’t a distinction between lock_for_read and lock_for_write, instead there is a single lock keyword.

 

The meaning is that if you have many threads coming in and trying to read from the shared resource, they would have to queue and enter the block one by one.

 

The ReaderWriterLock allow multiple threads to access a read block at the same time, so they will only need to wait once a thread is asking for a write lock. Then the writing thread will wait for all other threads within synchronised blocks to complete, then do its thing.

 

Sounds great, isn’t it?

 

Well, actually the benefit of a ReaderWriterLock will only be in place when these two conditions are in place:

why? because if the block executes very fast, then the waiting read threads will not need to actually queue up.

And if writes are not very sparse, an exclusive lock (because of the writes) will be taken many times, causing reading threads to queue anyway.

 

Adhering to the “no free gifts” rule, the usage of a ReaderWriterLock has more overhead than that of a Monitor, thus it would not be advisable to consider using the ReaderWriterLock unless you know for sure that the two aforementioned conditions will take place in the scenario.

 

And even then, you one should beware of a problem that might happen since there isn’t a syntactic sugar for the ReaderWriterLock. Since you have to release the lock yourself, the common usage pattern is:


ReaderWriterLockSlim locker = new ReaderWriterLockSlim();
...
// read block
locker.EnterReadLock();
try
{     //readAction
}
finally
{     locker.ExitReadLock();
}


// write block
locker.EnterWriteLock();
try
{     //write Action
}
finally
{     locker.ExitWriteLock();
}

 

Since I know that the usage is not 100% trivial, and that I might forget to exit the lock in a finally block (I’ve seen code examples around the interweb that forget to do so), I am usually looking up previous code of mine, and then copy-and-paste it.

Since like many other developers I tend to be lazy and sloppy when copy-pasting boring pieces of code around, I end up doing some mistakes such as entering a read lock, however exiting a write lock. I then get weird runtime exceptions that it takes a good few minutes to figure out. annoying.

This is without taking UpgradeableReadLock into account, which (imo) does not have a trivial API.  I will put a separate post explaining UpgradeableReadLock btw.

 

Summary:

 

Now since I found myself needing to use a ReaderWriterLock more than once lately, and since I did repeat the stupid copy-and-paste mistakes more than once, I created a little helper for that, included in my old-ish D9.Commons project, which is where I through reusable pieces of code at. Which reminds me that I need to move it to github some when soon.

Meanwhile it is at http://code.google.com/p/d-9/source/browse/trunk/src/D9.Commons/D9.Commons/Locks/Lock.cs, and it contains shortcut methods for executing code within Read, Write and UpgradeableRead blocks.

I’ll run a different post with a couple of usage snippets later.

Using generic classes and avoid locks

  

In D9.Commons, there’s a class responsible for mapping from enum values to their respective description, and vice versa - DescribedEnumHandler.cs

The initial API I had in mind was


var enumValue = Enums.From<MyEnum>("The description");

var enumDescription = Enums.ToDescription(MyEnum.Something);

The Enums class would hold an IDictionary to map from the given Enum type, to it’s DescribedEnumHandler

Then came the question: when should I initialise that map, and how should I allow access to it?

Solution 1: Synchronise access to the map.

Cons: every access to the Enums methods will require synchronisation code.

Solution 2: Allow only one point of initialisation, through a static Initialise(…) method, accepting enum types, or assemblies with enums. This method will be called when the application loads, and after all of the enums are initialised, all the following usages will be lock free.

Cons:

a. It’s ugly.

b. You end up creating way too many handlers, even if you won’t use most or even any of them.

c. It really is ugly. You don’t believe me? look here.

Solution 3: Instead of using Generic methods (From<T> and ToDescription<T>), I changed the Enums class to a generic Enum<T> class.

within the class, there’s a single static member, DescribedEnumHandler of T.

Every call to Enum<T> for a new T will instantiate the needed handler, Just In Time.

That’s because with generic types, every concrete type is a new type, so List<int> and List<long> are two separate types, without any inheritance relationship between them, so their static members are not shared.

That’s the class I ended up with: Enums.cs

Described Enums in NHibernate

  

First feature in D9.NHibernate: DescribedEnumStringType

That’s a generic IUserType for mapping enum columns using the descriptions of values instead of their names.

It depends on D9.Commons which contains the Described Enum helpers described in an early post

Usage:

given the following enum:

usingSystem.ComponentModel;

namespaceOpenUni.Domain.Modules
{
    publicenumModuleTypes
    {
        [Description("ר")]
        Standard,

        [Description("מ")]
        Advanced,

        [Description("מס")]
        AdvancedSeminar,

        [Description("תש")]
        Masters
    }
}

mapping a field of type ModuleTypes will look like that:

&lt;propertyname    = "ModuleType"column  = "ModuleType"type    = "D9.NHibernate.UserTypes.DescribedEnumStringType`1[[OpenUni.Domain.Modules.ModuleTypes, OpenUni.Domain]], 
              D9.NHibernate" /&gt;

or if you use Castle ActiveRecord attributes for mapping:

[Property(ColumnType = "D9.NHibernate.UserTypes.DescribedEnumStringType`1[[OpenUni.Domain.Modules.ModuleTypes, OpenUni.Domain]], D9.NHibernate")]
public virtual ModuleTypes ModuleType {get; set;}

Code is here:

http://code.google.com/p/d-9/source/browse/#svn/trunk

I’ll build and upload binaries once I get some time for that. meanwhile you should be able to just svn-co the code, then nant from the root. (assuming nant 0.86b2 and .net 3.5 on the machine)


Follow @kenegozi