summaryrefslogtreecommitdiff
path: root/docs/tutorials/Chap_6/ex09.html
blob: e641da20bc5cd154505af0676086c3fce8502d41 (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
<HTML>
<HEAD>
   <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
   <META NAME="Author" CONTENT="Ambreen Ilyas">
   <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]">
   <TITLE>Example 9</TITLE>
</HEAD>
<BODY>
<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT>
<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers
Guide.</FONT>
<BR><FONT COLOR="#CC0000">////&nbsp; Chapter:&nbsp; "The Acceptor/Connector"&nbsp;
(Connection Initialization)</FONT>
<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT>
<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT>
<BR><FONT COLOR="#CC0000">////&nbsp; AUTHOR: Umar Syyid (usyyid@hns.com)</FONT>
<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT>
<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT>

<P><FONT COLOR="#CC0000">//Example 9</FONT>
<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Reactor.h"</FONT>
<BR><FONT COLOR="#000099">#include</FONT><FONT COLOR="#663366"> </FONT><FONT COLOR="#006600">"ace/Svc_Handler.h"</FONT>
<BR><FONT COLOR="#000099">#include</FONT><FONT COLOR="#006600"> "ace/Connector.h"</FONT>
<BR><FONT COLOR="#000099">#include</FONT><FONT COLOR="#006600"> "ace/Synch.h"</FONT>
<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/SOCK_Connector.h"</FONT>
<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/INET_Addr.h"</FONT>

<P><FONT COLOR="#000099">#define</FONT> <FONT COLOR="#663366">PORT_NUM
10101</FONT>
<BR><FONT COLOR="#000099">#define</FONT> <FONT COLOR="#663366">DATA_SIZE
16</FONT>

<P><FONT COLOR="#FF0000">//forward declaration</FONT>
<BR>class My_Svc_Handler;
<BR><FONT COLOR="#FF0000">//Function prototype</FONT>
<BR>static void make_connections(void *arg);

<P><FONT COLOR="#FF0000">// Template specializations for the hashing function
for the</FONT>
<BR><FONT COLOR="#FF0000">// hash_map which is used by the cache. The cache
is used internally by the</FONT>
<BR><FONT COLOR="#FF0000">// Cached Connection Strategy . Here we use ACE_Hash_Addr</FONT>
<BR><FONT COLOR="#FF0000">// as our external identifier. This utility class
has already</FONT>
<BR><FONT COLOR="#FF0000">// overloaded the == operator and the hash()
method. (The</FONT>
<BR><FONT COLOR="#FF0000">// hashing function). The hash() method delgates
the work to</FONT>
<BR><FONT COLOR="#FF0000">// hash_i() and we use the IP address and port
to get a</FONT>
<BR><FONT COLOR="#FF0000">// a unique integer hash value.</FONT>
<BR>size_t
<BR>ACE_Hash_Addr&lt;ACE_INET_Addr>::hash_i (const ACE_INET_Addr &amp;addr)
const
<BR>{
<BR>&nbsp; return addr.get_ip_address () + addr.get_port_number ();
<BR>}

<P><FONT COLOR="#FF0000">//instantiate a strategy acceptor</FONT>
<BR>typedef ACE_Strategy_Connector&lt;My_Svc_Handler,ACE_SOCK_CONNECTOR>
<BR>STRATEGY_CONNECTOR;

<P><FONT COLOR="#FF0000">//Instantiate the Creation Strategy</FONT>
<BR>typedef ACE_NOOP_Creation_Strategy&lt;My_Svc_Handler>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NULL_CREATION_STRATEGY;
<BR><FONT COLOR="#FF0000">//Instantiate the Concurrency Strategy</FONT>
<BR>typedef ACE_NOOP_Concurrency_Strategy&lt;My_Svc_Handler>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NULL_CONCURRENCY_STRATEGY;
<BR><FONT COLOR="#FF0000">//Instantiate the Connection Strategy</FONT>
<BR>typedef ACE_Cached_Connect_Strategy&lt;My_Svc_Handler,
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
ACE_SOCK_CONNECTOR,
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
ACE_SYNCH_RW_MUTEX>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CACHED_CONNECT_STRATEGY;
<BR>&nbsp;
<BR>class My_Svc_Handler:
<BR>public ACE_Svc_Handler &lt;ACE_SOCK_STREAM,ACE_MT_SYNCH>{
<BR>private:
<BR>char* data;

<P>public:
<BR>My_Svc_Handler(){
<BR>data= new char[DATA_SIZE];
<BR>&nbsp;}
<BR>My_Svc_Handler(ACE_Thread_Manager* tm){
<BR>data= new char[DATA_SIZE];
<BR>&nbsp;}
<BR><FONT COLOR="#FF0000">//Called before the service handler is recycled..</FONT>
<BR>int
<BR>recycle (void *a=0){
<BR>&nbsp;&nbsp; ACE_DEBUG ((LM_DEBUG,
<BR>&nbsp;&nbsp;&nbsp; "(%P|%t) recycling Svc_Handler %d with handle %d\n",
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
this, this->peer ().get_handle ()));
<BR>&nbsp;return 0;
<BR>&nbsp;}

<P>int open(void*){
<BR>&nbsp;ACE_DEBUG((LM_DEBUG,"(%t)Connection established \n"));
<BR>&nbsp;
<BR>&nbsp;
<BR>&nbsp;

<P><FONT COLOR="#FF0000">&nbsp;//Register the service handler with the
reactor</FONT>
<BR>&nbsp;ACE_Reactor::instance() ->register_handler(this,ACE_Event_Handler::READ_MASK);
<BR>&nbsp;activate(THR_NEW_LWP|THR_DETACHED);
<BR>&nbsp;return 0;
<BR>&nbsp;}

<P>int handle_input(ACE_HANDLE){
<BR>&nbsp;ACE_DEBUG((LM_DEBUG,"Got input in thread: (%t) \n"));
<BR>&nbsp;peer().recv_n(data,DATA_SIZE);
<BR>&nbsp;ACE_DEBUG((LM_DEBUG,"&lt;&lt; %s\n",data));

<P>&nbsp;<FONT COLOR="#FF0000">//keep yourself registered with the reactor</FONT>
<BR>&nbsp;return 0;
<BR>}

<P>int svc(void){
<BR><FONT COLOR="#FF0000">&nbsp;//send a few messages and then mark connection
as idle so that it can be recycled later.</FONT>
<BR>&nbsp;ACE_DEBUG((LM_DEBUG,"Started the service routine \n"));

<P>&nbsp;for(int i=0;i&lt;3;i++){
<BR>&nbsp; ACE_DEBUG((LM_DEBUG,"(%t)>>Hello World\n"));
<BR>&nbsp; ACE_OS::fflush(stdout);
<BR>&nbsp; peer().send_n("Hello World",sizeof("Hello World"));
<BR>&nbsp; }

<P>&nbsp;<FONT COLOR="#FF0000">//Mark the service handler as being idle
now and let the other threads reuse this connection</FONT>
<BR>&nbsp;this->idle(1);

<P>&nbsp;<FONT COLOR="#FF0000">//Wait for the thread to die</FONT>
<BR>&nbsp;this->thr_mgr()->wait();
<BR>&nbsp;return 0;
<BR>&nbsp;}
<BR>};
<BR>ACE_INET_Addr *addr;

<P>int main(int argc, char* argv[]){
<BR>&nbsp;addr= new ACE_INET_Addr(PORT_NUM,argv[1]);
<BR><FONT COLOR="#FF0000">&nbsp;//Creation Strategy</FONT>
<BR>&nbsp;NULL_CREATION_STRATEGY creation_strategy;

<P><FONT COLOR="#FF0000">&nbsp;//Concurrency Strategy</FONT>
<BR>&nbsp;&nbsp; NULL_CONCURRENCY_STRATEGY concurrency_strategy;

<P><FONT COLOR="#FF0000">&nbsp;//Connection Strategy</FONT>
<BR>&nbsp;CACHED_CONNECT_STRATEGY caching_connect_strategy;
<BR>&nbsp;

<P><FONT COLOR="#FF0000">&nbsp;//instantiate the connector</FONT>
<BR>&nbsp;STRATEGY_CONNECTOR connector(
<BR>&nbsp;&nbsp; ACE_Reactor::instance(),<FONT COLOR="#FF0000"> //the reactor
to use</FONT>
<BR>&nbsp;&nbsp; &amp;creation_strategy,
<BR>&nbsp;&nbsp; &amp;caching_connect_strategy,
<BR>&nbsp;&nbsp; &amp;concurrency_strategy);
<BR><FONT COLOR="#FF0000">&nbsp;//Use the thread manager to&nbsp; spawn
a single thread to</FONT>
<BR><FONT COLOR="#FF0000">&nbsp;//connect multiple times passing it the
address</FONT>
<BR><FONT COLOR="#FF0000">&nbsp;//of the strategy connector</FONT>
<BR>&nbsp;if(ACE_Thread_Manager::instance()->spawn(
<BR>&nbsp;&nbsp;&nbsp; (ACE_THR_FUNC) make_connections,
<BR>&nbsp;&nbsp;&nbsp; (void *) &amp;connector,
<BR>&nbsp;&nbsp;&nbsp; THR_NEW_LWP) == -1)
<BR>&nbsp;ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n%a", "client thread spawn
failed"));

<P>while(1) /* Start the reactor?s event loop */
<BR>&nbsp;ACE_Reactor::instance()->handle_events();
<BR>}

<P><FONT COLOR="#FF0000">//Connection establishment function, tries to
establish connections</FONT>
<BR><FONT COLOR="#FF0000">//to the same server again and re-uses the connections
from the</FONT>
<BR><FONT COLOR="#FF0000">//cache</FONT>
<BR>void make_connections(void *arg){
<BR>&nbsp;ACE_DEBUG((LM_DEBUG,"(%t)Prepared to connect \n"));
<BR>&nbsp;STRATEGY_CONNECTOR *connector= (STRATEGY_CONNECTOR*) arg;
<BR>&nbsp;for (int i = 0; i &lt; 10; i++){
<BR>&nbsp;My_Svc_Handler *svc_handler = 0;
<BR>&nbsp;

<P>&nbsp;<FONT COLOR="#FF0000">// Perform a blocking connect to the server
using the Strategy</FONT>
<BR><FONT COLOR="#FF0000">&nbsp;// Connector with a connection caching
strategy.&nbsp; Since we are</FONT>
<BR><FONT COLOR="#FF0000">&nbsp;// connecting to the same &lt;server_addr>
these calls will return the</FONT>
<BR><FONT COLOR="#FF0000">&nbsp;// same dynamically allocated &lt;Svc_Handler>
for each &lt;connect> call.</FONT>
<BR>&nbsp;if (connector->connect (svc_handler, *addr) == -1){
<BR>&nbsp; ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n", "connection failed\n"));
<BR>&nbsp; return;
<BR>&nbsp; }

<P><FONT COLOR="#FF0000">&nbsp;// Rest for a few seconds so that the connection
has been freed up</FONT>
<BR>&nbsp;ACE_OS::sleep (5);
<BR>&nbsp;}
<BR>}
<BR>&nbsp;
<BR>&nbsp;<A HREF="ex10.html">Next Example</A>
</BODY>
</HTML>