Announcement

Sunday, August 09, 2009

Implementing a Well behaved Singleton - 4

In part-3 of this series, I talked about implementing singleton such that construction sequence is guaranteed and the destruction is guaranteed however the sequence in which the destruction happens is not guaranteed.

Sometimes one singleton object depends on another singleton object. In such cases, the technique described in part-3 will be useful to ensure that the singleton's are constructed in the correct order. However, since it uses the 'function static objects' , the destruction sequence is compiler dependent. Suppose Singleton object Foo depends on singleton object Bar, this technique will ensure correct order of construction. However, compiler may call the destructors of Foo and Bar in the wrong order, since compiler is not aware of this dependency.

To fix the destruction sequence we will take the help of little known function called 'atexit'. You can find the details of 'atexit' here. or in the compiler help. The important property is If more than one atexit function has been specified by different calls to this function, they are all executed in reverse order as a stack, i.e. the last function specified is the first to be executed at exit. This is property we need to ensure that the singltons are destructed in the 'reverser order' of their construction.


class FooSingleton
{
public:
~FooSingleton(void);
static FooSingleton& GetSingleton(void);

private :
FooSingleton(void);
static void DestroySingleton(void);

private :
static FooSingleton* m_pFoo;
int m_var;
};

////////////////////////////////
// In the .cpp file
FooSingleton::m_pFoo = NULL;

FooSingleton::FooSingleton(void)
{
//...
// Code construct foo singleton
::atexit(FooSingleton::DestroySingleton); // THIS IS KEY }
}

FooSingleton&
FooSingleton::GetSingleton(void)
{
if( m_pFoo == NULL)
{
m_pFoo = new FooSingleton;
}
return(*m_pFoo);
}

void
FooSingleton::DestroySingleton(void)
{
delete m_pFoo;
}

Now if FooSingleton and BarSingleton objects are coded in similar way and FooSingleton depends on BarSingleton then 'FooSingleton::GetSingleton' will call BarSingleton::GetSingleton(). Hence the BarSingleton will get constructed first and in the process the BarSingleton::DestroySingleton function will get registered with 'atexit. Next FooSingleton::DestroySingleton will get registered with 'atexit'.

When program exits, the functions registered with 'atexit' will be called in the reverse order of registration. Hence the FooSingleton::DestroySingleton will get called first and then BarSingleton::DestroySingleton.

Now we have ensured that the singleton objects are destructed in the reverse order of their construction sequence. This technique is completely 'standards compliant' and hence should work on all C++ compilers.

Many developers have misconception that Singleton is the easiest design pattern to implement. As you can see implementing a 'well behaved' singleton is NOT such an easy problem to solve.

Saturday, August 01, 2009

Visualizing Code Duplication in a project

Treemap visualization is an excellent way to visualize the information/various metrics about the directory tree (e.g. source files directory tree). I have used treemaps for visualizing SourceMonitor metrics about entire project with excellent results. Unfortunately there are very few simple and opensource treemap visualization softwares available. There is JTreemap applet which can be use to view csv files as treemaps. Sometime back an Excel plugin was available from Microsoft Research site. However, there is no trace of it now on the Microsoft research site.

As part of Thinking Craftsman Toolkit, I wrote a simple Tkinter/Python treemap viewer to view the SourceMonitor metrics as treemaps. After writing initial version of Code Duplication Detector, I realized there is no good visualization tool to visually check the 'proliferation' of duplication across various files/directories. The tools like Simian or CPD just give a list of duplications. I thought 'Treemaps' can be excellent tool to visualize the duplication. Hence I added '-t' flag to CDD. This flag displays the treemap view of the Code Duplication. You can see the screen snapshot of the treemap view here.(See the thumbnail below)