summaryrefslogtreecommitdiff
path: root/docs/tutorials/013/page03.html
blob: 6a3fdd798e83250da0898866f0a0a710bddeeeee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
<HTML>
<HEAD>
   <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
   <META NAME="Author" CONTENT="James CE Johnson">
   <TITLE>ACE Tutorial 013</TITLE>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F">

<CENTER><B><FONT SIZE=+2>ACE Tutorial 013</FONT></B></CENTER>

<CENTER><B><FONT SIZE=+2>Multiple thread pools</FONT></B></CENTER>


<P>
<HR WIDTH="100%">
<P>
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.
<P>
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.
<P>
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.
<P>
Simple, cheap, effective.
<P>
<HR WIDTH="100%">
<PRE>
#include "ace/Synch.h"
#include "ace/Singleton.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()

<HR WIDTH="50%">
<i>In the cpp file we have this:</i>

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();
}

</PRE>
<HR WIDTH="100%">
<CENTER>[<A HREF="..">Tutorial Index</A>] [<A HREF="page04.html">Continue
This Tutorial</A>]</CENTER>

</BODY>
</HTML>