summaryrefslogtreecommitdiff
path: root/docs/tutorials/006/page03.html
blob: b9dad643a4e203c447e7ad758299d8e25a098a7a (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
<HTML>
<HEAD>
   <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
   <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]">
   <META NAME="Author" CONTENT="James CE Johnson">
   <META NAME="Description" CONTENT="A first step towards using ACE productively">
   <TITLE>ACE Tutorial 006</TITLE>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F">

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

<CENTER><B><FONT SIZE=+2>Creating a thread-per-connection server</FONT></B></CENTER>


<P>
<HR WIDTH="100%">

<P>In <A HREF="client_acceptor.h">client_acceptor.h</A>, we've extended
our object just a bit.&nbsp; The primary reason is to allow us to select
the previous single-threaded implementation or our new thread-per-connection
implementation.&nbsp; Client_Acceptor itself doesn't use this information
but makes it available to the Client_Handler objects it creates.&nbsp;
If we wanted a single-strategy implementation, we would have made no changes
to the Tutorial 5 version of this file.

<P>
<HR WIDTH="100%">

<P><FONT FACE="Arial,Helvetica">// $Id: client_acceptor.h,v 1.1 1998/08/30
13:38:27 jcej Exp $</FONT><FONT FACE="Arial,Helvetica"></FONT>

<P><FONT FACE="Arial,Helvetica">#ifndef CLIENT_ACCEPTOR_H</FONT>
<BR><FONT FACE="Arial,Helvetica">#define CLIENT_ACCEPTOR_H</FONT><FONT FACE="Arial,Helvetica"></FONT>

<P><FONT FACE="Arial,Helvetica">/*</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; The ACE_Acceptor&lt;> template
lives in the ace/Acceptor.h header file. You'll</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; find a very consitent naming
convention between the ACE objects and the</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; headers where they can be
found.&nbsp; In general, the ACE object ACE_Foobar will</FONT>
<BR><FONT FACE="Arial,Helvetica"></FONT>&nbsp;<FONT FACE="Arial,Helvetica"></FONT>

<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; be found in ace/Foobar.h.</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT><FONT FACE="Arial,Helvetica"></FONT>

<P><FONT FACE="Arial,Helvetica">#include "ace/Acceptor.h"</FONT><FONT FACE="Arial,Helvetica"></FONT>

<P><FONT FACE="Arial,Helvetica">/*</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; Since we want to work with
sockets, we'll need a SOCK_Acceptor to allow the</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; clients to connect to us.</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT>
<BR><FONT FACE="Arial,Helvetica">#include "ace/SOCK_Acceptor.h"</FONT><FONT FACE="Arial,Helvetica"></FONT>

<P><FONT FACE="Arial,Helvetica">/*</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; The Client_Handler object
we develop will be used to handle clients once</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; they're connected.&nbsp;
The ACE_Acceptor&lt;> template's first parameter requires</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; such an object.&nbsp; In
some cases, you can get by with just a forward</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; declaration on the class,
in others you have to have the whole thing.</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT>
<BR><FONT FACE="Arial,Helvetica">#include "client_handler.h"</FONT><FONT FACE="Arial,Helvetica"></FONT>

<P><FONT FACE="Arial,Helvetica">/*</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; Parameterize the ACE_Acceptor&lt;>
such that it will listen for socket</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; connection attempts and create
Client_Handler objects when they happen. In</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; Tutorial 001, we wrote the
basic acceptor logic on our own before we</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; realized that ACE_Acceptor&lt;>
was available.&nbsp; You'll get spoiled using the</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; ACE templates because they
take away a lot of the tedious details!</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT>
<BR><FONT FACE="Arial,Helvetica">typedef ACE_Acceptor &lt; Client_Handler,
ACE_SOCK_ACCEPTOR > Client_Acceptor_Base;</FONT><FONT FACE="Arial,Helvetica"></FONT>

<P><FONT FACE="Arial,Helvetica">/*</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; Here, we use the parameterized
ACE_Acceptor&lt;> as a baseclass for our customized</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; Client_Acceptor object.&nbsp;
I've done this so that we can provide it with our choice</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; of concurrency strategies
when the object is created.&nbsp; Each Client_Handler it</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; creates will use this information
to determine how to act.&nbsp; If we were going</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; to create a system that was
always thread-per-connection, we would not have</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; bothered to extend&nbsp;
Client_Acceptor.</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT>
<BR><FONT FACE="Arial,Helvetica">class Client_Acceptor : public Client_Acceptor_Base</FONT>
<BR><FONT FACE="Arial,Helvetica">{</FONT>
<BR><FONT FACE="Arial,Helvetica">public:</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
/*</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
This is always a good idea.&nbsp; If nothing else, it makes your code more</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
orthogonal no matter what baseclasses your objects have.</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
*/</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
typedef Client_Acceptor_Base inherited;</FONT><FONT FACE="Arial,Helvetica"></FONT>

<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
/*</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Construct the object with the concurrency strategy.&nbsp; Since this tutorial</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
is focused on thread-per-connection, we make that the default.&nbsp; We
could</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
have chosen to omitt the default and populate it in main() instead.</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
*/</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Client_Acceptor( int _thread_per_connection = 1 )</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
: thread_per_connection_(_thread_per_connection)</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
{</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
}</FONT><FONT FACE="Arial,Helvetica"></FONT>

<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
/*</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Return the value of our strategy flag.&nbsp; This is used by the Client_Handler</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
to decide how to act.&nbsp; If 'true' then the handler will behave in a</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
thread-per-connection manner.</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
*/</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
int thread_per_connection(void)</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
{ return this->thread_per_connection_; }</FONT><FONT FACE="Arial,Helvetica"></FONT>

<P><FONT FACE="Arial,Helvetica">protected:</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
int thread_per_connection_;</FONT><FONT FACE="Arial,Helvetica"></FONT>

<P><FONT FACE="Arial,Helvetica">};</FONT><FONT FACE="Arial,Helvetica"></FONT>

<P><FONT FACE="Arial,Helvetica">#endif // CLIENT_ACCEPTOR_H</FONT>

<P>
<HR WIDTH="100%">

<P>Ok, so far we haven't done much to change our concurrency strategy.&nbsp;
Let's move on to the Client_Handler and see if it has changed any.

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

</BODY>
</HTML>