Merge pull request #2303 from jwillemsen/jwi-803
[ACE_TAO.git] / TAO / examples / Buffered_AMI / client.cpp
blobf3412e15a68b15696759b4e471cb4f24aef6a0b6
2 //=============================================================================
3 /**
4 * @file client.cpp
6 * This is a client that uses buffered AMI calls.
8 * @author Irfan Pyarali
9 */
10 //=============================================================================
13 #include "testS.h"
14 #include "tao/Messaging/Messaging.h"
15 #include "tao/AnyTypeCode/Any.h"
16 #include "tao/AnyTypeCode/TAOA.h"
17 #include "ace/Get_Opt.h"
18 #include "ace/Read_Buffer.h"
20 // Name of file contains ior.
21 static const ACE_TCHAR *IOR = ACE_TEXT ("file://ior");
23 // Default iterations.
24 static CORBA::ULong iterations = 20;
26 // Default number of invocations to buffer before flushing.
27 static CORBA::Long message_count = iterations / 4;
29 // Time interval between invocation (in milli seconds).
30 static long interval = 1000;
32 // Flag indicates whether to shutdown remote server or not upon client
33 // shutdown.
34 static int shutdown_server = 0;
36 // AMI call or regular call.
37 static int invoke_ami_style = 1;
39 // Setup buffering or not.
40 static int setup_buffering = 1;
42 // Flag indicates that all replies have been received
43 static int received_all_replies = 0;
45 class Reply_Handler : public POA_AMI_testHandler
47 public:
48 void method (CORBA::ULong reply_number)
50 ACE_DEBUG ((LM_DEBUG,
51 "client: AMI Reply %d @ %T\n",
52 reply_number));
54 // Last reply flips the flag.
55 if (reply_number == iterations)
56 received_all_replies = 1;
59 void method_excep (::Messaging::ExceptionHolder *holder)
61 try
63 holder->raise_exception ();
65 catch (const CORBA::SystemException& ex)
67 ex._tao_print_exception ("Reply_Handler::method_excep: ");
71 //FUZZ: disable check_for_lack_ACE_OS
72 void shutdown ()
75 //FUZZ: enable check_for_lack_ACE_OS
77 void shutdown_excep (::Messaging::ExceptionHolder *holder)
79 try
81 holder->raise_exception ();
83 catch (const CORBA::SystemException& ex)
85 ex._tao_print_exception ("Reply_Handler::shutdown_excep: ");
90 static int
91 parse_args (int argc, ACE_TCHAR **argv)
93 ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("a:b:k:m:i:t:x"));
94 int c;
96 while ((c = get_opts ()) != -1)
97 switch (c)
99 case 'k':
100 IOR = get_opts.opt_arg ();
101 break;
103 case 'm':
104 message_count = ACE_OS::atoi (get_opts.opt_arg ());
105 break;
107 case 'a':
108 invoke_ami_style = ACE_OS::atoi (get_opts.opt_arg ());
109 break;
111 case 'b':
112 setup_buffering = ACE_OS::atoi (get_opts.opt_arg ());
113 break;
115 case 'i':
116 iterations = ACE_OS::atoi (get_opts.opt_arg ());
117 break;
119 case 't':
120 interval = ACE_OS::atoi (get_opts.opt_arg ());
121 break;
123 case 'x':
124 shutdown_server = 1;
125 break;
127 case '?':
128 default:
129 ACE_ERROR_RETURN ((LM_ERROR,
130 "usage: %s "
131 "-k IOR "
132 "-m message count "
133 "-a invoke AMI style [0/1] "
134 "-b setup buffering [0/1] "
135 "-i iterations "
136 "-t interval between calls "
137 "-x shutdown server "
138 "\n",
139 argv [0]),
140 -1);
143 if (IOR == 0)
144 ACE_ERROR_RETURN ((LM_ERROR,
145 "Please specify the IOR for the servant\n"), -1);
147 // Without AMI, replies are immediate.
148 if (!invoke_ami_style)
149 received_all_replies = 1;
151 // Message count must be a multiple of iterations; otherwise we'll
152 // have some unsent messages left in the buffered queue. Even
153 // though we can explicitly flush the queue, I am being lazy and
154 // forcing the user to give the right numbers.
155 if ((iterations % message_count) != 0)
157 ACE_ERROR_RETURN ((LM_ERROR,
158 "<message_count> must be a multiple <iterations> "
159 "or the program should be changed to flush explicitly\n"),
160 -1);
163 // Indicates successful parsing of command line.
164 return 0;
167 void
168 setup_buffering_constraints (CORBA::ORB_ptr orb)
170 // Obtain PolicyCurrent.
171 CORBA::Object_var object = orb->resolve_initial_references ("PolicyCurrent");
173 // Narrow down to correct type.
174 CORBA::PolicyCurrent_var policy_current =
175 CORBA::PolicyCurrent::_narrow (object.in ());
177 // Start off with no constraints.
178 TAO::BufferingConstraint buffering_constraint;
179 buffering_constraint.mode = TAO::BUFFER_MESSAGE_COUNT;
180 buffering_constraint.message_count = message_count;
181 buffering_constraint.message_bytes = 0;
182 buffering_constraint.timeout = 0;
184 // Setup the buffering constraint any.
185 CORBA::Any buffering_constraint_any;
186 buffering_constraint_any <<= buffering_constraint;
188 // Setup the buffering constraint policy list.
189 CORBA::PolicyList buffering_constraint_policy_list (1);
190 buffering_constraint_policy_list.length (1);
192 // Setup the buffering constraint policy.
193 buffering_constraint_policy_list[0] =
194 orb->create_policy (TAO::BUFFERING_CONSTRAINT_POLICY_TYPE,
195 buffering_constraint_any);
197 // Setup the constraints (at the ORB level).
198 policy_current->set_policy_overrides (buffering_constraint_policy_list,
199 CORBA::ADD_OVERRIDE);
201 // We are done with the policy.
202 buffering_constraint_policy_list[0]->destroy ();
204 // Setup the none sync scope policy, i.e., the ORB will buffer AMI
205 // calls.
206 Messaging::SyncScope sync_none = Messaging::SYNC_NONE;
208 // Setup the none sync scope any.
209 CORBA::Any sync_none_any;
210 sync_none_any <<= sync_none;
212 // Setup the none sync scope policy list.
213 CORBA::PolicyList sync_none_policy_list (1);
214 sync_none_policy_list.length (1);
216 // Setup the none sync scope policy.
217 sync_none_policy_list[0] =
218 orb->create_policy (Messaging::SYNC_SCOPE_POLICY_TYPE,
219 sync_none_any);
221 // Setup the none sync scope (at the ORB level).
222 policy_current->set_policy_overrides (sync_none_policy_list,
223 CORBA::ADD_OVERRIDE);
225 // We are now done with these policies.
226 sync_none_policy_list[0]->destroy ();
230 ACE_TMAIN (int argc, ACE_TCHAR *argv[])
234 // Initialize the ORB.
235 CORBA::ORB_var orb =
236 CORBA::ORB_init (argc, argv);
238 // Initialize options based on command-line arguments.
239 int parse_args_result = parse_args (argc, argv);
240 if (parse_args_result != 0)
241 return parse_args_result;
243 CORBA::Object_var base =
244 orb->resolve_initial_references ("RootPOA");
246 PortableServer::POA_var root_poa =
247 PortableServer::POA::_narrow (base.in ());
249 // Get an object reference from the argument string.
250 base = orb->string_to_object (IOR);
252 PortableServer::POAManager_var poa_manager =
253 root_poa->the_POAManager ();
255 poa_manager->activate ();
257 // Try to narrow the object reference to a <test> reference.
258 test_var test_object = test::_narrow (base.in ());
260 Reply_Handler reply_handler_servant;
261 AMI_testHandler_var reply_handler_object = reply_handler_servant._this ();
263 if (setup_buffering)
265 setup_buffering_constraints (orb.in ());
268 for (CORBA::ULong i = 1; i <= iterations; ++i)
270 ACE_DEBUG ((LM_DEBUG,
271 "client: Iteration %d @ %T\n",
272 i));
274 if (invoke_ami_style)
276 // Invoke the AMI method.
277 test_object->sendc_method (reply_handler_object.in (),
280 else
282 CORBA::ULong reply_number = 0;
284 // Invoke the regular method.
285 test_object->method (i,
286 reply_number);
288 ACE_DEBUG ((LM_DEBUG,
289 "client: Regular Reply %d @ %T\n",
290 reply_number));
293 // Interval between successive calls.
294 ACE_Time_Value sleep_interval (0,
295 interval * 1000);
297 orb->run (sleep_interval);
300 // Loop until all replies have been received.
301 while (!received_all_replies)
303 orb->perform_work ();
306 // Shutdown server.
307 if (shutdown_server)
309 test_object->shutdown ();
312 root_poa->destroy (true, true);
314 // Destroy the ORB. On some platforms, e.g., Win32, the socket
315 // library is closed at the end of main(). This means that any
316 // socket calls made after main() fail. Hence if we wait for
317 // static destructors to flush the queues, it will be too late.
318 // Therefore, we use explicit destruction here and flush the
319 // queues before main() ends.
320 orb->destroy ();
322 catch (const CORBA::Exception& ex)
324 ex._tao_print_exception ("Exception caught:");
325 return -1;
328 return 0;