summaryrefslogtreecommitdiff
path: root/docs/tutorials/016/page03.html
blob: 4c4077a415ae75bad1be82f9153796e6629f45da (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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
<HTML>
<HEAD>
   <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
   <META NAME="Author" CONTENT="James CE Johnson">
   <TITLE>ACE Tutorial 016</TITLE>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F">

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

<CENTER><B><FONT SIZE=+2>Making ACE_Condition easier to use</FONT></B></CENTER>

<P>
<HR WIDTH="100%">
Ok, now we'll take a look at the definition of the class.  You already
know how to use an ACE_Condition & it's not really that difficult.
Still, imagine how much more cluttered your code would be if it had to 
include the mess I've got below!
<HR>
<PRE>

<font color=red>// $Id$</font>

<font color=red>// Get or declaration</font>
<font color=blue>#include</font> "<font color=green>Condition_i.h</font>"

<font color=red>/* Initialize the condition variable and create the condition mutex.
   Since I don't have any guarantees on the order of member variable
   initialization, I have to new the condition mutex instead of
   simply constructing it.
 */</font>
<font color=#008888>Condition::Condition</font>(value_t _value)
        : value_(_value)
{
    condition_ = new condition_t( this->mutex() );
}

<font color=#008888>Condition::~Condition</font>(void)
{
     <font color=red>// Be sure we don't have a memeory leak</font>
    delete condition_;
}

<font color=red>/* The cast operator is the easiest way to return a copy of the value
   to clients of the class.  It also allows us to use a private method 
   for getting a reference to the value when we need to modify it.
 */</font>
<font color=#008888>Condition::operator</font> Condition::value_t (void)
{
     <font color=red>// Place a guard around the variable so that it won't change as</font>
     <font color=red>// we're copying it back to the client.</font>
    guard_t    guard(mutex_);
    return value();
}

<font color=red>/* Traditional prefix increment operator.
   We place a guard around the operation so that we don't collide with 
   any other threads.  After the modification, we broadcast() a
   condition change to any waiting threads.  You can also use signal() 
   but that will only tell one thread about the change.  If that
   thread, in turn, invokes signal() then all threads will eventually
   find out.  I just thought it would be easier to use broadcast() and 
   be done with it.
 */</font>
Condition & <font color=#008888>Condition::operator</font>++ (void)
{
    guard_t    guard(mutex_);

    ++value();

    condition().broadcast();

    return *this;
}

<font color=red>/* The remaining operators all follow the same pattern that we have
   above.  They only differ in the modification they make to the value().
 */</font>

Condition & <font color=#008888>Condition::operator</font>-- (void)
{
    guard_t    guard(mutex_);

    --value();

    condition().broadcast();

    return *this;
}

Condition & <font color=#008888>Condition::operator</font>+= (int _inc)
{
    guard_t    guard(mutex_);

    value() += _inc;

    condition().broadcast();

    return *this;
}

Condition & <font color=#008888>Condition::operator</font>-= (int _inc)
{
    guard_t    guard(mutex_);

    value() -= _inc;

    condition().broadcast();

    return *this;
}

Condition & <font color=#008888>Condition::operator</font>*= (int _inc)
{
    guard_t    guard(mutex_);

    value() *= _inc;

    condition().broadcast();

    return *this;
}

Condition & <font color=#008888>Condition::operator</font>/= (int _inc)
{
    guard_t    guard(mutex_);

    value() /= _inc;

    condition().broadcast();

    return *this;
}

Condition & <font color=#008888>Condition::operator</font>%= (int _inc)
{
    guard_t    guard(mutex_);

    value() %= _inc;

    condition().broadcast();

    return *this;
}

Condition & <font color=#008888>Condition::operator</font>= ( value_t _value )
{
    guard_t    guard(mutex_);

    value() = _value;

    condition().broadcast();

    return *this;
}

<font color=red>/* Now we get into the comparison area.
   Each one follows the pattern we've already established for
   waiters.
 */</font>

<font color=red>/*
   We begin with an equality operator that expects a function object.
   In the while() test we pass a copy of the value to the function
   object for evaluation.  The object can then do any comparision it
   wants to check for a desired condition.  When the function object
   returns non-zero, the condition is met and we leave.
 */</font>
int <font color=#008888>Condition::operator</font>== ( Condition::Compare & _compare )
{
    guard_t    guard(mutex_);

    while( ! _compare(this->value()) )
        condition().wait();

    return 0;
}

<font color=red>// As long as the variable equals _value, we wait...</font>
int <font color=#008888>Condition::operator</font>== ( value_t _value )
{
    guard_t    guard(mutex_);

    while( value() == _value )
        condition().wait();

    return 0;
}

<font color=red>// As long as the variable is not equal to _value, we wait...</font>
int <font color=#008888>Condition::operator</font>!= ( value_t _value )
{
    guard_t    guard(mutex_);

    while( value() != _value )
        condition().wait();

    return 0;
}

<font color=red>// As long as the variable is less than or equal to _value, we wait...</font>
int <font color=#008888>Condition::operator</font>&lt;= ( value_t _value )
{
    guard_t    guard(mutex_);

    while( value() &lt;= _value )
        condition().wait();

    return 0;
}

<font color=red>// As long as the variable is greater than or equal to _value, we wait...</font>
int <font color=#008888>Condition::operator</font>>= ( value_t _value )
{
    guard_t    guard(mutex_);

    while( value() >= _value )
        condition().wait();

    return 0;
}
</PRE>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page04.html">Continue This Tutorial</A>]</CENTER>