ACE Tutorial 013
Multiple thread pools


I did eventually create that ACE_Data_Block derivative that I wanted. My purpose in doing so was to use the reference-counting that is provided by ACE_Data_Block and ACE_Message_Block interactions. When you're working with an object in a single thread, it's generally not so difficult to manage it's lifetime. That is, it doesn't tend to go out of scope or get destroyed unless you do it on purpose.

On the other hand, if you're passing data between several threads, it is easy to loose track of who "owns" the data at any one time. All too frequently, data will be deleted by one thread while another is still using it. Reference counting can prevent that. The rule of thumb is that you increment the reference count of the object when you hand it off to a new thread. You then decrement the count when you're done with the object and let the object delete itself when there are no more references.

To prove that all of that works correctly in the tutorial, I've created a cheap Memory Leak Detector object. All mld instances reference a thread-safe counter that is incremented when the mld is constructed and decremented when destructed. I then insert an mld into each of my dynamically created objects. If I get to the end of main() and the counter isn't zero then I either didn't delete enough or I deleted too many times.

Simple, cheap, effective.



mld.h


// $Id$

#ifndef MLD_H
#define MLD_H

#include "ace/Synch.h"

#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */

#include "ace/Singleton.h"
#include "ace/Atomic_Op.h"

/*
   This is a cheap memory leak detector.  Each class I want to watch over
   contains an mld object.  The mld object's ctor increments a global counter
   while the dtor decrements it.  If the counter is non-zero when the program
   is ready to exit then there may be a leak.
 */

class mld
{
public:
    mld (void);
    ~mld (void);

    static int value (void);

protected:
    static ACE_Atomic_Op < ACE_Mutex, int >counter_;
};

// ================================================

/*
   Just drop 'MLD' anywhere in your class definition to get cheap memory leak
   detection for your class.
 */
#define MLD            mld mld_

/*
   Use 'MLD_COUNTER' in main() to see if things are OK.
 */
#define MLD_COUNTER    mld::value()

// ================================================

#endif

mld.cpp


// $Id$

#include "mld.h"

ACE_Atomic_Op < ACE_Mutex, int >mld::counter_ (0);

// Increment the counter when a new mld is created...
mld::mld (void)
{
    ++counter_;
}

// and decrement it when the object is destructed.
mld::~mld (void)
{
    --counter_;
}

int mld::value (void)
{
    return counter_.value ();
}


[Tutorial Index] [Continue This Tutorial]