~ubuntu-branches/ubuntu/breezy/ace/breezy

« back to all changes in this revision

Viewing changes to docs/tutorials/012/page05.html

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad, Benjamin Montgomery, Adam Conrad
  • Date: 2005-09-18 22:51:38 UTC
  • mfrom: (1.2.1 upstream) (2.1.1 sarge) (0.1.2 woody)
  • Revision ID: james.westby@ubuntu.com-20050918225138-seav22q6fyylb536
Tags: 5.4.7-3ubuntu1
[ Benjamin Montgomery ]
* Added a patch for amd64 and powerpc that disables the compiler
  option -fvisibility-inlines-hidden

[ Adam Conrad ]
* Added DPATCH_OPTION_CPP=1 to debian/patches/00options to make
  Benjamin's above changes work correctly with dpatch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
<!-- page05.html,v 1.10 2000/03/19 20:09:26 jcej Exp -->
2
 
<HTML>
3
 
<HEAD>
4
 
   <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
5
 
   <META NAME="Author" CONTENT="James CE Johnson">
6
 
   <TITLE>ACE Tutorial 012</TITLE>
7
 
</HEAD>
8
 
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F">
9
 
 
10
 
<CENTER><B><FONT SIZE=+2>ACE Tutorial 012</FONT></B></CENTER>
11
 
 
12
 
<CENTER><B><FONT SIZE=+2>Passing classes through ACE_Message_Queue</FONT></B></CENTER>
13
 
 
14
 
 
15
 
<P>
16
 
<HR WIDTH="100%">
17
 
<P>
18
 
The Task is the only object we've not been through yet.  I'll go ahead
19
 
and show both the header and cpp on this one page since the header
20
 
isn't very large.
21
 
<P>
22
 
<HR WIDTH="100%">
23
 
<HR width=50%><P><center>task.h</center><HR width=50%>
24
 
<PRE>
25
 
 
26
 
<font color=red>// page05.html,v 1.10 2000/03/19 20:09:26 jcej Exp</font>
27
 
 
28
 
<font color=blue>#ifndef</font> <font color=purple>TASK_H</font>
29
 
<font color=blue>#define</font> <font color=purple>TASK_H</font>
30
 
 
31
 
<font color=blue>#include</font> "<A HREF="../../../ace/Task.h">ace/Task.h</A>"
32
 
 
33
 
<font color=blue>#if !defined</font> (<font color=purple>ACE_LACKS_PRAGMA_ONCE</font>)
34
 
<font color=blue># pragma</font> <font color=purple>once</font>
35
 
<font color=blue>#endif</font> <font color=red>/* ACE_LACKS_PRAGMA_ONCE */</font>
36
 
 
37
 
<font color=red>/*
38
 
  This is our basic thread-pool Task.  We have a choice of pool size
39
 
  on the open() and the usual svc() and close() methods.
40
 
 
41
 
  A new addition is the ACE_Barrier object.  This will allow the
42
 
  synchronization of our svc() methods so that they all start at the
43
 
  "<font color=green>same</font>" time.  The normal case may allow one thread to start working
44
 
  earlier than others.  There's no real harm in it but you can get
45
 
  better "<font color=green>work by thread</font>" statistics if they start out together.
46
 
*/</font>
47
 
class Task : public ACE_Task &lt; ACE_MT_SYNCH >
48
 
{
49
 
public:
50
 
 
51
 
    typedef ACE_Task &lt; ACE_MT_SYNCH > inherited;
52
 
 
53
 
    Task (void);
54
 
    ~Task (void);
55
 
 
56
 
    <font color=red>/*
57
 
      I really wanted this to be called open() but that was already
58
 
      claimed by the Task framework.  start() will kick off our thread
59
 
      pool for us.
60
 
    */</font>
61
 
    int start (int threads = 1);
62
 
 
63
 
    virtual int svc (void);
64
 
 
65
 
    virtual int close (u_long flags = 0);
66
 
 
67
 
protected:
68
 
    ACE_Barrier * barrier_;
69
 
};
70
 
 
71
 
<font color=blue>#endif</font>
72
 
</PRE>
73
 
<HR width=50%><P><center>task.cpp</center><HR width=50%>
74
 
<PRE>
75
 
 
76
 
<font color=red>// page05.html,v 1.10 2000/03/19 20:09:26 jcej Exp</font>
77
 
 
78
 
<font color=blue>#include</font> "<font color=green>task.h</font>"
79
 
<font color=blue>#include</font> "<font color=green>block.h</font>"
80
 
<font color=blue>#include</font> "<font color=green>work.h</font>"
81
 
 
82
 
<font color=red>/*
83
 
  Boring default constructor.  Be sure our barrier_ is initialized in
84
 
  case we get destructed before opened.
85
 
*/</font>
86
 
<font color=#008888>Task::Task</font> (void)
87
 
: barrier_ (0)
88
 
{
89
 
  ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) Task ctor 0x%x\n</font>", (void *) this));
90
 
}
91
 
 
92
 
<font color=red>/*
93
 
  You'll see in the svc() method that when we get a shutdown request,
94
 
  we always putq() it back into our message queue.  The last thread in
95
 
  the pool will do this also and result in there always being one
96
 
  shutdown request left in the queue when we get here.  Just to be
97
 
  polite, we'll go ahead and get that message and release it.
98
 
 
99
 
  We also delete the barrier_ object we used to synch the svc()
100
 
  methods.
101
 
*/</font>
102
 
<font color=#008888>Task::~Task</font> (void)
103
 
{
104
 
  ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) Task dtor 0x%x\n</font>", (void *) this));
105
 
 
106
 
  ACE_Message_Block *message;
107
 
  this->getq (message);
108
 
  message->release ();
109
 
 
110
 
  delete barrier_;
111
 
}
112
 
 
113
 
<font color=red>/*
114
 
  The ACE_Barrier needs to know how many threads it will be working
115
 
  for.  For that reason, we have to put off it's construction until we
116
 
  get here.  We then pass the thread count through to our base class'
117
 
  activate().
118
 
*/</font>
119
 
int <font color=#008888>Task::start</font> (int threads)
120
 
{
121
 
  barrier_ = new ACE_Barrier (threads);
122
 
  return this->activate (THR_NEW_LWP, threads);
123
 
}
124
 
 
125
 
<font color=red>/*
126
 
  We don't really do anything here but I wanted to provide a message
127
 
  in the output.
128
 
*/</font>
129
 
int <font color=#008888>Task::close</font> (u_long flags)
130
 
{
131
 
  ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) Task close 0x%x\n</font>", (void *) this));
132
 
  return <font color=#008888>inherited::close</font> (flags);
133
 
}
134
 
 
135
 
<font color=red>/*
136
 
  Now the svc() method where everything interesting happens.
137
 
*/</font>
138
 
int <font color=#008888>Task::svc</font> (void)
139
 
{
140
 
     <font color=red>/*
141
 
       All of the threads will block here until the last thread
142
 
       arrives.  They will all then be free to begin doing work.
143
 
     */</font>
144
 
  this->barrier_->wait ();
145
 
 
146
 
  ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) Task 0x%x starts in thread %u\n</font>", (void *) this, <font color=#008888>ACE_Thread::self</font> ()));
147
 
 
148
 
   <font color=red>// Where we getq() the message</font>
149
 
  ACE_Message_Block *message;
150
 
   <font color=red>// What we really put into the queue is a Message_Block, so we'll</font>
151
 
   <font color=red>// cast the 'message' to 'message_block' after getting it.  I'm</font>
152
 
   <font color=red>// going through some extra steps here just to be explicit</font>
153
 
  Message_Block * message_block;
154
 
   <font color=red>// The baseclass of the work object we put into the queue.  Notice</font>
155
 
   <font color=red>// that we can use this and not bother with the Work object at all.</font>
156
 
  Unit_Of_Work * unit_of_work;
157
 
 
158
 
  while (1)
159
 
  {
160
 
       <font color=red>// Get the message...</font>
161
 
    if (this->getq (message) == -1)
162
 
    {
163
 
      ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>getq</font>"), -1);
164
 
    }
165
 
 
166
 
     <font color=red>// Is it a shutdown request?</font>
167
 
    if (message->msg_type () == <font color=#008888>ACE_Message_Block::MB_HANGUP</font>)
168
 
    {
169
 
         <font color=red>// Send the shutdown to all of our pool peers</font>
170
 
      this->putq (message);
171
 
      break;
172
 
    }
173
 
 
174
 
     <font color=red>// Cast the pointer to our specialized Message_Block.  We could</font>
175
 
     <font color=red>// have done this at the getq() call but I wanted to be explicit</font>
176
 
     <font color=red>// about what we're doing here</font>
177
 
    message_block = (Message_Block*)message;
178
 
 
179
 
     <font color=red>/*
180
 
       Since we left alone the ACE_Data_Block used by the
181
 
       Message_Block we have chosen to use it to send arbitrary data
182
 
       as well.
183
 
     */</font>
184
 
    const char *cp = message_block->rd_ptr ();
185
 
     <font color=red>// Don't forget to skip the NULL we inserted</font>
186
 
    message_block->rd_ptr (strlen (cp) + 1);
187
 
 
188
 
     <font color=red>/*
189
 
       Get the Unit_Of_Work pointer out of our specialized
190
 
       Message_Block.  Since the methods of interest are virtual, we
191
 
       don't have to know what kind of work we're to do.
192
 
     */</font>
193
 
    unit_of_work = message_block->data();
194
 
 
195
 
    <font color=red>/*
196
 
       Invoke a couple of method calls on the object we constructed.
197
 
     */</font>
198
 
    unit_of_work->who_am_i ();
199
 
    unit_of_work->what_am_i ();
200
 
 
201
 
    ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) Block 0x%x contains (%s)\n</font>", (void *) message, cp));
202
 
 
203
 
     <font color=red>/*
204
 
       Pretend that the work takes a little time to process.  This
205
 
       prevents one thread from getting all of the action.  In a real
206
 
       system you wouldn't need to do this since the work really
207
 
       would take time to complete.
208
 
     */</font>
209
 
    <font color=#008888>ACE_OS::sleep</font> (ACE_Time_Value (0, 5000));
210
 
 
211
 
     <font color=red>/*
212
 
       Release the message block and allow the unit of work to also go
213
 
       away.
214
 
     */</font>
215
 
    message->release ();
216
 
  }
217
 
 
218
 
  return (0);
219
 
}
220
 
</PRE>
221
 
<HR WIDTH="100%">
222
 
<P>
223
 
Like main() this is actually simpler than the previous tutorial.  It's
224
 
much cleaner to carry around a pointer to the object we're working
225
 
with than to try copying data.
226
 
<P>
227
 
The only complication is the new ACE_Barrier.  It's a pretty simple
228
 
object that makes it easy for you to synch threads in this way.  You
229
 
could do some fancy tricks with mutexes, counters & semaphores but why
230
 
bother when the Barrier already exists.
231
 
<P>
232
 
<P><HR WIDTH="100%">
233
 
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page06.html">Continue This Tutorial</A>]</CENTER>
234