ACE+TAO-7_0_8
[ACE_TAO.git] / TAO / tests / RTCORBA / RTMutex / server.cpp
blobf1fb70b5967385215cf10e9b77583ea86da14141
1 #include "tao/ORB.h"
2 #include "tao/RTCORBA/RTCORBA.h"
3 #include "ace/Thread_Manager.h"
4 #include "ace/High_Res_Timer.h"
5 #include "ace/Get_Opt.h"
6 #include "ace/OS_NS_unistd.h"
8 static int test_try_lock_flag =
9 #if defined (ACE_HAS_MUTEX_TIMEOUTS) && !defined (ACE_HAS_WTHREADS)
11 #else
12 // Don't test try_lock timed waits unless the underlying OS supports it
13 // Windows is the exception. It supports some mutex timeouts, so
14 // it has ACE_HAS_MUTEX_TIMEOUTS defined, but it doesn't support
15 // thread mutex timeouts which is what is needed for this to work.
17 #endif /* defined (ACE_HAS_MUTEX_TIMEOUTS) && !defined (ACE_HAS_WTHREADS) */
19 // Parse command-line arguments.
21 static int
22 parse_args (int argc, ACE_TCHAR *argv[])
24 ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("t"));
25 int c;
27 while ((c = get_opts ()) != -1)
28 switch (c)
30 case 't':
31 test_try_lock_flag = 0;
32 break;
34 case '?':
35 default:
36 ACE_ERROR_RETURN ((LM_ERROR,
37 "usage: %s "
38 "-t"
39 "\n",
40 argv [0]),
41 -1);
44 return 0;
47 static int
48 check_for_nil (CORBA::Object_ptr obj, const char *msg)
50 if (CORBA::is_nil (obj))
51 ACE_ERROR_RETURN ((LM_ERROR,
52 "ERROR: Object reference <%C> is nil\n",
53 msg),
54 -1);
55 else
56 return 0;
59 static int
60 test_mutex_simple (RTCORBA::RTORB_ptr rt_orb)
62 // Test the basic interface of the RTCORBA::Mutex This test should
63 // run even on platforms without thread support.
64 try
66 RTCORBA::Mutex_var my_mutex;
68 my_mutex = rt_orb->create_mutex ();
70 my_mutex->lock ();
72 my_mutex->unlock ();
74 my_mutex->lock ();
76 my_mutex->unlock ();
78 rt_orb->destroy_mutex (my_mutex.in ());
81 catch (const CORBA::Exception& ex)
83 ex._tao_print_exception (
84 "Unexpected exception caught in test_mutex_simple()");
85 return -1;
88 return 0;
91 #if (TAO_HAS_NAMED_RT_MUTEXES == 1)
92 static int
93 test_named_mutex_simple (RTCORBA::RTORB_ptr rt_orb)
95 // Test the basic interface of the named RTCORBA::Mutex(es) This
96 // test should run even on platforms without thread support.
97 try
99 RTCORBA::Mutex_var larry_mutex1;
100 RTCORBA::Mutex_var moe_mutex1;
101 CORBA::Boolean created_flag;
103 larry_mutex1 = rt_orb->create_named_mutex ("larry",
104 created_flag);
106 if (created_flag != 1)
107 ACE_ERROR_RETURN ((LM_ERROR,
108 "ERROR: Expected named mutex larry to be created, but it wasn't\n"),
109 -1);
111 moe_mutex1 = rt_orb->create_named_mutex ("moe",
112 created_flag);
114 if (created_flag != 1)
115 ACE_ERROR_RETURN ((LM_ERROR,
116 "ERROR: Expected named mutex moe to be created, but it wasn't\n"),
117 -1);
119 larry_mutex1->lock ();
121 larry_mutex1->unlock ();
123 // Test creating the mutex a second time
125 RTCORBA::Mutex_var larry_mutex2;
126 larry_mutex2 = rt_orb->create_named_mutex ("larry",
127 created_flag);
129 if (created_flag != 0)
130 ACE_ERROR_RETURN ((LM_ERROR,
131 "ERROR: Expected named mutex to already be created, but it wasn't\n"),
132 -1);
134 // test the pointers...
135 if (reinterpret_cast<void *> (larry_mutex1.in ())
136 != reinterpret_cast<void *> (larry_mutex2.in ()))
137 ACE_ERROR_RETURN ((LM_ERROR,
138 "ERROR: Should have gotten the same mutex, but didn't\n"),
139 -1);
141 larry_mutex2->lock ();
143 larry_mutex2->unlock ();
146 // test opening the mutex
148 RTCORBA::Mutex_var larry_mutex3;
149 larry_mutex3 = rt_orb->open_named_mutex ("larry");
151 // test the pointers...
152 if (reinterpret_cast<void *> (larry_mutex1.in ())
153 != reinterpret_cast<void *> (larry_mutex3.in ()))
154 ACE_ERROR_RETURN ((LM_ERROR,
155 "ERROR: Should have gotten the same mutex, but didn't\n"),
156 -1);
158 larry_mutex3->lock ();
160 larry_mutex3->unlock ();
163 // Make sure that nothing has been broken behind the scenes.
164 larry_mutex1->lock ();
166 larry_mutex1->unlock ();
168 rt_orb->destroy_mutex (larry_mutex1.in ());
170 rt_orb->destroy_mutex (moe_mutex1.in ());
172 catch (const CORBA::Exception& ex)
174 ex._tao_print_exception (
175 "Unexpected exception caught in test_named_mutex_simple()");
176 return -1;
179 return 0;
182 static int
183 test_named_mutex_exception (RTCORBA::RTORB_ptr rt_orb)
185 // Test that open_named_mutex returns an exception when the mutex
186 // name isn't found.
188 // This test should run even on platforms without thread support.
191 RTCORBA::Mutex_var larry_mutex1;
193 larry_mutex1 = rt_orb->open_named_mutex ("larry");
195 ACE_ERROR_RETURN ((LM_ERROR,
196 "Expected a MutexNotFound exception, but didn't get one.\n"),
197 -1);
199 catch (const RTCORBA::RTORB::MutexNotFound& ex)
201 ACE_DEBUG ((LM_DEBUG, "Caught expected MutexNotFound exception.\n"));
203 catch (const CORBA::Exception& ex)
205 ex._tao_print_exception (
206 "Unexpected exception caught in test_named_mutex_exception()");
207 return -1;
210 return 0;
212 #endif /* TAO_HAS_NAMED_RT_MUTEXES == 1 */
214 #if defined (ACE_HAS_THREADS)
215 const size_t MAX_ITERATIONS=10;
216 const size_t MAX_THREADS=4;
218 struct Mutex_Test_Data
220 RTCORBA::Mutex_ptr mutex;
221 int *shared_var;
222 int *error_flag;
225 static void *
226 mutex_test_thread (void *args)
228 Mutex_Test_Data *data = reinterpret_cast<Mutex_Test_Data *> (args);
230 RTCORBA::Mutex_ptr mutex = data->mutex;
231 int *shared_var = data->shared_var;
233 ACE_OS::srand (static_cast<u_int> (ACE_OS::time (0)));
237 for (size_t i = 0; i < MAX_ITERATIONS / 2; i++)
239 ACE_DEBUG ((LM_DEBUG,
240 ACE_TEXT ("(%P|%t) = trying to lock on iteration %d\n"),
241 i));
242 mutex->lock ();
244 ACE_DEBUG ((LM_DEBUG,
245 ACE_TEXT ("(%P|%t) = locked on iteration %d\n"),
246 i));
248 // Check if the shared var is a value it shouldn't be when
249 // we're under the lock.
250 if (*shared_var != 0)
252 ACE_ERROR ((LM_ERROR,
253 "Expected shared_var to be 0 under the mutex\n"));
254 *data->error_flag = 1;
257 *shared_var = 1;
259 // Sleep for a random amount of time between 0 and 2
260 // seconds. Note that it's ok to use rand() here because we
261 // are running within the critical section defined by the
262 // Thread_Mutex.
263 ACE_OS::sleep (ACE_OS::rand () % 2);
265 if (*shared_var != 1)
267 ACE_ERROR ((LM_ERROR,
268 "Expected shared_var to still be 1 after sleeping\n"));
269 *data->error_flag = 1;
272 *shared_var = 0;
274 mutex->unlock ();
276 ACE_DEBUG ((LM_DEBUG,
277 ACE_TEXT ("(%P|%t) = unlocked on iteration %d\n"),
278 i));
281 catch (const CORBA::Exception& ex)
283 ex._tao_print_exception (
284 "Unexpected exception caught in mutex_test_thread()");
285 *data->error_flag = 1;
288 return 0;
291 static int
292 test_mutex_threads (RTCORBA::RTORB_ptr rt_orb)
294 // test the RTCORBA::Mutex implementation be spawning many threads
295 // that repeatedly content for a lock. This code is based on the
296 // tests/Thread_Mutex_Test code.
298 Mutex_Test_Data test_data;
300 const u_int n_threads = MAX_THREADS;
301 int shared_var = 0;
302 int error_flag = 0;
306 RTCORBA::Mutex_ptr mutex = rt_orb->create_mutex ();
308 test_data.mutex = mutex;
309 test_data.shared_var = &shared_var;
310 test_data.error_flag = &error_flag;
312 if (ACE_Thread_Manager::instance ()->spawn_n (n_threads,
313 ACE_THR_FUNC (mutex_test_thread),
314 (void *) &test_data,
315 THR_NEW_LWP | THR_DETACHED) == -1)
316 ACE_ERROR ((LM_ERROR,
317 ACE_TEXT ("%p\n%a"),
318 ACE_TEXT ("thread create failed")));
320 // Wait for the threads to exit.
321 ACE_Thread_Manager::instance ()->wait ();
323 CORBA::release (mutex);
326 catch (const CORBA::Exception& ex)
328 ex._tao_print_exception (
329 "Unexpected exception caught in test_mutex_threads()");
330 return -1;
333 return error_flag;
336 static void *
337 mutex_test_try_lock_thread (void *args)
339 // test out try_lock() failure cases
340 Mutex_Test_Data *data = reinterpret_cast<Mutex_Test_Data *> (args);
342 RTCORBA::Mutex_ptr mutex = data->mutex;
343 CORBA::Boolean result;
347 // check that try_lock (0) returns false
348 ACE_DEBUG ((LM_DEBUG,"attempting try_lock (0) - expect failure (but no exceptions)\n"));
349 result = mutex->try_lock (0u);
351 if (result)
353 ACE_ERROR ((LM_ERROR,
354 "try_lock succeeded, but expected a failure\n"));
355 *data->error_flag = 1;
358 if (test_try_lock_flag)
360 ACE_High_Res_Timer timer;
362 // Check that try_lock (timeout) returns false (and times
363 // out)
364 ACE_DEBUG ((LM_DEBUG,
365 "attempting try_lock (5 sec) - expect failure after 5 secs (but no exceptions)\n"));
367 timer.start ();
368 result = mutex->try_lock (50000000u /*5sec*/);
369 timer.stop ();
371 if (result)
373 ACE_ERROR ((LM_ERROR,
374 "try_lock (timeout) succeeded, but expected a failure\n"));
375 *data->error_flag = 1;
378 ACE_Time_Value measured;
379 timer.elapsed_time (measured);
380 ACE_DEBUG ((LM_DEBUG,
381 "try_lock returned after %u secs, %u usecs\n",
382 measured.sec(),
383 measured.usec()));
385 if ((measured.sec() == 4 && measured.usec() >= 500000)
386 || (measured.sec() == 5 && measured.usec() <= 500000))
387 /* success */;
388 else
390 ACE_ERROR ((LM_ERROR,
391 "try_lock timed out not as expected\n"));
392 *data->error_flag = 1;
396 catch (const CORBA::Exception& ex)
398 ex._tao_print_exception (
399 "Unexpected exception caught in mutex_test_try_lock_thread()");
400 *data->error_flag = 1;
403 return 0;
406 static int
407 test_mutex_try_lock (RTCORBA::RTORB_ptr rt_orb)
409 Mutex_Test_Data test_data;
410 CORBA::Boolean result;
412 int shared_var = 0;
413 int error_flag = 0;
417 RTCORBA::Mutex_ptr mutex = rt_orb->create_mutex ();
419 // Test out try_lock and keep the lock so that the spawned task
420 // can test out try_lock failure cases
421 result = mutex->try_lock (0u);
422 if (!result)
423 ACE_ERROR_RETURN ((LM_ERROR,
424 "try_lock failed\n"),
425 -1);
427 test_data.mutex = mutex;
428 test_data.shared_var = &shared_var;
429 test_data.error_flag = &error_flag;
431 ACE_DEBUG ((LM_DEBUG,
432 "Spawning the test thread\n"));
433 if (ACE_Thread_Manager::instance ()->spawn (ACE_THR_FUNC (mutex_test_try_lock_thread),
434 (void *) &test_data,
435 THR_NEW_LWP | THR_DETACHED) == -1)
436 ACE_ERROR ((LM_ERROR,
437 ACE_TEXT ("%p\n%a"),
438 ACE_TEXT ("thread create failed")));
440 // Wait for the threads to exit.
441 ACE_Thread_Manager::instance ()->wait ();
443 mutex->unlock ();
445 CORBA::release (mutex);
448 catch (const CORBA::Exception& ex)
450 ex._tao_print_exception (
451 "Unexpected exception caught in test_mutex_try_lock()");
452 return -1;
455 return error_flag;
458 #endif /* ACE_HAS_THREADS */
461 ACE_TMAIN(int argc, ACE_TCHAR *argv[])
465 // ORB.
466 CORBA::ORB_var orb = CORBA::ORB_init (argc, argv);
468 // Parse arguments.
469 if (parse_args (argc, argv) != 0)
470 return -1;
472 // RTORB.
473 CORBA::Object_var object =
474 orb->resolve_initial_references ("RTORB");
475 RTCORBA::RTORB_var rt_orb = RTCORBA::RTORB::_narrow (object.in ());
476 if (check_for_nil (rt_orb.in (), "RTORB") == -1)
477 return -1;
479 ACE_DEBUG ((LM_DEBUG,
480 "Running RTCORBA Mutex unit tests\n"));
482 if (test_mutex_simple (rt_orb.in ()) != 0)
483 ACE_ERROR_RETURN ((LM_ERROR,
484 "test_mutex_simple failed\n"),
485 -1);
487 #if (TAO_HAS_NAMED_RT_MUTEXES == 1)
488 if (test_named_mutex_simple (rt_orb.in ()) != 0)
489 ACE_ERROR_RETURN ((LM_ERROR,
490 "test_named_mutex_simple failed\n"),
491 -1);
493 if (test_named_mutex_exception (rt_orb. in ()) != 0)
494 ACE_ERROR_RETURN ((LM_ERROR,
495 "test_named_mutex_exception failed\n"),
496 -1);
497 #else
498 ACE_DEBUG ((LM_DEBUG,
499 "Named RT_Mutex support is not enabled. "
500 "Skipping Named RT_Mutex tests.\n"));
501 #endif /* TAO_HAS_NAMED_RT_MUTEXES == 1 */
503 #if defined (ACE_HAS_THREADS)
505 if (test_mutex_threads (rt_orb.in ()) != 0)
506 ACE_ERROR_RETURN ((LM_ERROR,
507 "test_mutex_threads failed\n"),
508 -1);
509 else if (test_mutex_try_lock (rt_orb.in ()) != 0)
510 ACE_ERROR_RETURN ((LM_ERROR,
511 "test_mutex_try_lock failed\n"),
512 -1);
514 #endif /* ACE_HAS_THREADS */
516 ACE_DEBUG ((LM_DEBUG, "Mutex test finished\n\n"));
518 catch (const CORBA::Exception& ex)
520 ex._tao_print_exception (
521 "Unexpected exception caught in Mutex test server:");
522 return -1;
525 return 0;