Merge pull request #2301 from sonndinh/remove-dup-reactor-functions
[ACE_TAO.git] / TAO / tests / Bug_2909_Regression / client.cpp
blob2d46e423e5e1fd83840a3f0c4ae6d602de5a5a91
2 //=============================================================================
3 /**
4 * @file client.cpp
6 * A client which uses the AMI callback model and tests whether exceptions
7 * are redirected to the reply handler when client and servant are
9 * @author Johnny Willemsen <jwillemsen@remedy.nl>
11 //=============================================================================
14 #include "ace/Get_Opt.h"
15 #include "ace/Task.h"
16 #include "ace/Atomic_Op.h"
17 #include "ace/Synch_Traits.h"
18 #include "ami_test_i.h"
20 const ACE_TCHAR *ior = ACE_TEXT("file://test.ior");
21 int nthreads = 1;
22 int niterations = 2;
23 int debug = 0;
24 ACE_Atomic_Op<TAO_SYNCH_MUTEX, int> number_of_replies = 0;
26 int invalid_exception = 0;
28 int
29 parse_args (int argc, ACE_TCHAR *argv[])
31 ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("dk:n:i:"));
32 int c;
34 while ((c = get_opts ()) != -1)
35 switch (c)
37 case 'd':
38 debug = 1;
39 break;
40 case 'k':
41 ior = get_opts.opt_arg ();
42 break;
43 case 'n':
44 nthreads = ACE_OS::atoi (get_opts.opt_arg ());
45 break;
46 case 'i':
47 niterations = ACE_OS::atoi (get_opts.opt_arg ());
48 break;
49 case '?':
50 default:
51 ACE_ERROR_RETURN ((LM_ERROR,
52 "usage: %s "
53 "-d "
54 "-k <ior> "
55 "-n <nthreads> "
56 "-i <niterations> "
57 "\n",
58 argv [0]),
59 -1);
61 // Indicates successful parsing of the command line
62 return 0;
66 /**
67 * @class Client
69 * @brief Run the client thread
71 * Use the ACE_Task_Base class to run the client threads.
73 class Client : public ACE_Task_Base
75 public:
76 /// ctor
77 Client (A::AMI_Test_ptr server, int niterations);
79 /// The thread entry point.
80 virtual int svc ();
82 // private:
83 /// Var for the AMI_Test object.
84 A::AMI_Test_var ami_test_var_;
86 /// The number of iterations on each client thread.
87 int niterations_;
89 /// Var for AMI_AMI_Test_ReplyHandler object.
90 A::AMI_AMI_TestHandler_var the_handler_var_;
93 class Handler : public POA_A::AMI_AMI_TestHandler
95 public:
96 Handler () : request_ (0)
100 void foo ()
102 int const reply = --number_of_replies;
104 if (debug)
106 ACE_DEBUG ((LM_DEBUG,
107 "(%P | %t) : Callback method %d called\n",
108 (nthreads * niterations) - reply));
110 ACE_UNUSED_ARG (reply);
111 ++request_;
114 void foo_excep (::Messaging::ExceptionHolder * excep_holder)
116 int const reply = --number_of_replies;
117 if (debug)
119 ACE_DEBUG ((LM_DEBUG,
120 "(%P | %t) : Callback excep method %d called\n",
121 (nthreads * niterations) - reply));
123 ACE_UNUSED_ARG (reply);
126 excep_holder->raise_exception ();
128 catch (const A::DidTheRightThing& ex)
130 if (request_ != 0)
132 ++invalid_exception;
133 ex._tao_print_exception ("Caught exception:");
135 else
137 ACE_DEBUG ((LM_DEBUG, "Caught correct exception\n"));
140 catch (const CORBA::UNKNOWN& ex)
142 if (request_ != 1)
144 ++invalid_exception;
145 ex._tao_print_exception ("Caught exception:");
147 else
149 ACE_DEBUG ((LM_DEBUG, "Caught correct exception\n"));
152 ++request_;
155 ~Handler ()
158 private:
159 int request_;
162 // ReplyHandler.
163 Handler handler;
166 ACE_TMAIN(int argc, ACE_TCHAR *argv[])
170 CORBA::ORB_var orb =
171 CORBA::ORB_init (argc, argv);
173 if (parse_args (argc, argv) != 0)
174 return 1;
176 A::AMI_Test_var server;
178 AMI_Test_i * servant =
179 new AMI_Test_i(orb.in());
180 PortableServer::ServantBase_var safe (servant);
182 server = servant->_this();
184 if (CORBA::is_nil (server.in ()))
186 ACE_ERROR_RETURN ((LM_ERROR,
187 "Object reference <%s> is nil.\n",
188 ior),
192 // Activate POA to handle the call back.
194 CORBA::Object_var poa_object =
195 orb->resolve_initial_references("RootPOA");
197 if (CORBA::is_nil (poa_object.in ()))
198 ACE_ERROR_RETURN ((LM_ERROR,
199 " (%P|%t) Unable to initialize the POA.\n"),
202 PortableServer::POA_var root_poa =
203 PortableServer::POA::_narrow (poa_object.in ());
205 PortableServer::POAManager_var poa_manager =
206 root_poa->the_POAManager ();
208 poa_manager->activate ();
210 // Main thread collects replies. It needs to collect
211 // <nthreads*niterations> replies.
212 number_of_replies = nthreads * niterations;
214 // Let the client perform the test in a separate thread
216 Client client (server.in (), niterations);
217 if (client.activate (THR_NEW_LWP | THR_JOINABLE,
218 nthreads) != 0)
219 ACE_ERROR_RETURN ((LM_ERROR,
220 "Cannot activate client threads\n"),
223 if (debug)
225 ACE_DEBUG ((LM_DEBUG,
226 "(%P|%t) : Entering perform_work loop to receive <%d> replies\n",
227 number_of_replies.value ()));
230 // ORB loop.
232 while (number_of_replies > 0)
234 CORBA::Boolean pending = orb->work_pending();
236 if (pending)
238 orb->perform_work();
241 // On some systems this loop must yield or else the other threads
242 // will not get a chance to run.
243 ACE_OS::thr_yield();
246 if (debug)
248 ACE_DEBUG ((LM_DEBUG,
249 "(%P|%t) : Exited perform_work loop Received <%d> replies\n",
250 (nthreads*niterations) - number_of_replies.value ()));
253 client.thr_mgr ()->wait ();
255 ACE_DEBUG ((LM_DEBUG, "threads finished\n"));
257 root_poa->destroy (true, // ethernalize objects
258 false); // wait for completion
260 orb->destroy ();
262 catch (const CORBA::Exception& ex)
264 ex._tao_print_exception ("Caught exception:");
265 return 1;
268 return invalid_exception;
271 // ****************************************************************
273 Client::Client (A::AMI_Test_ptr server,
274 int niterations)
275 : ami_test_var_ (A::AMI_Test::_duplicate (server)),
276 niterations_ (niterations)
278 the_handler_var_ = handler._this (/* */);
282 Client::svc ()
286 for (int i = 0; i < this->niterations_; ++i)
288 ami_test_var_->sendc_foo (the_handler_var_.in (), i);
290 if (debug)
292 ACE_DEBUG ((LM_DEBUG,
293 "(%P | %t):<%d> Asynchronous methods issued\n",
294 niterations));
297 catch (const CORBA::Exception& ex)
299 ex._tao_print_exception ("MT_Client: exception raised");
300 invalid_exception = 1;
302 return 0;