Merge pull request #2218 from jwillemsen/jwi-pthreadsigmask
[ACE_TAO.git] / TAO / tests / RTCORBA / RTMutex / server.cpp
blob6253d484e707b9c7b8f0ba1f76b580dce8c2342f
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 ());
80 catch (const CORBA::Exception& ex)
82 ex._tao_print_exception (
83 "Unexpected exception caught in test_mutex_simple()");
84 return -1;
87 return 0;
90 #if (TAO_HAS_NAMED_RT_MUTEXES == 1)
91 static int
92 test_named_mutex_simple (RTCORBA::RTORB_ptr rt_orb)
94 // Test the basic interface of the named RTCORBA::Mutex(es) This
95 // test should run even on platforms without thread support.
96 try
98 RTCORBA::Mutex_var larry_mutex1;
99 RTCORBA::Mutex_var moe_mutex1;
100 CORBA::Boolean created_flag;
102 larry_mutex1 = rt_orb->create_named_mutex ("larry",
103 created_flag);
105 if (created_flag != 1)
106 ACE_ERROR_RETURN ((LM_ERROR,
107 "ERROR: Expected named mutex larry to be created, but it wasn't\n"),
108 -1);
110 moe_mutex1 = rt_orb->create_named_mutex ("moe",
111 created_flag);
113 if (created_flag != 1)
114 ACE_ERROR_RETURN ((LM_ERROR,
115 "ERROR: Expected named mutex moe to be created, but it wasn't\n"),
116 -1);
118 larry_mutex1->lock ();
120 larry_mutex1->unlock ();
122 // Test creating the mutex a second time
124 RTCORBA::Mutex_var larry_mutex2;
125 larry_mutex2 = rt_orb->create_named_mutex ("larry",
126 created_flag);
128 if (created_flag != 0)
129 ACE_ERROR_RETURN ((LM_ERROR,
130 "ERROR: Expected named mutex to already be created, but it wasn't\n"),
131 -1);
133 // test the pointers...
134 if (reinterpret_cast<void *> (larry_mutex1.in ())
135 != reinterpret_cast<void *> (larry_mutex2.in ()))
136 ACE_ERROR_RETURN ((LM_ERROR,
137 "ERROR: Should have gotten the same mutex, but didn't\n"),
138 -1);
140 larry_mutex2->lock ();
142 larry_mutex2->unlock ();
145 // test opening the mutex
147 RTCORBA::Mutex_var larry_mutex3;
148 larry_mutex3 = rt_orb->open_named_mutex ("larry");
150 // test the pointers...
151 if (reinterpret_cast<void *> (larry_mutex1.in ())
152 != reinterpret_cast<void *> (larry_mutex3.in ()))
153 ACE_ERROR_RETURN ((LM_ERROR,
154 "ERROR: Should have gotten the same mutex, but didn't\n"),
155 -1);
157 larry_mutex3->lock ();
159 larry_mutex3->unlock ();
162 // Make sure that nothing has been broken behind the scenes.
163 larry_mutex1->lock ();
165 larry_mutex1->unlock ();
167 rt_orb->destroy_mutex (larry_mutex1.in ());
169 rt_orb->destroy_mutex (moe_mutex1.in ());
171 catch (const CORBA::Exception& ex)
173 ex._tao_print_exception (
174 "Unexpected exception caught in test_named_mutex_simple()");
175 return -1;
178 return 0;
181 static int
182 test_named_mutex_exception (RTCORBA::RTORB_ptr rt_orb)
184 // Test that open_named_mutex returns an exception when the mutex
185 // name isn't found.
187 // This test should run even on platforms without thread support.
190 RTCORBA::Mutex_var larry_mutex1;
192 larry_mutex1 = rt_orb->open_named_mutex ("larry");
194 ACE_ERROR_RETURN ((LM_ERROR,
195 "Expected a MutexNotFound exception, but didn't get one.\n"),
196 -1);
198 catch (const RTCORBA::RTORB::MutexNotFound& ex)
200 ACE_DEBUG ((LM_DEBUG, "Caught expected MutexNotFound exception.\n"));
202 catch (const CORBA::Exception& ex)
204 ex._tao_print_exception (
205 "Unexpected exception caught in test_named_mutex_exception()");
206 return -1;
209 return 0;
211 #endif /* TAO_HAS_NAMED_RT_MUTEXES == 1 */
213 #if defined (ACE_HAS_THREADS)
214 const size_t MAX_ITERATIONS=10;
215 const size_t MAX_THREADS=4;
217 struct Mutex_Test_Data
219 RTCORBA::Mutex_ptr mutex;
220 int *shared_var;
221 int *error_flag;
224 static void *
225 mutex_test_thread (void *args)
227 Mutex_Test_Data *data = reinterpret_cast<Mutex_Test_Data *> (args);
229 RTCORBA::Mutex_ptr mutex = data->mutex;
230 int *shared_var = data->shared_var;
232 ACE_OS::srand (static_cast<u_int> (ACE_OS::time (0)));
236 for (size_t i = 0; i < MAX_ITERATIONS / 2; i++)
238 ACE_DEBUG ((LM_DEBUG,
239 ACE_TEXT ("(%P|%t) = trying to lock on iteration %d\n"),
240 i));
241 mutex->lock ();
243 ACE_DEBUG ((LM_DEBUG,
244 ACE_TEXT ("(%P|%t) = locked on iteration %d\n"),
245 i));
247 // Check if the shared var is a value it shouldn't be when
248 // we're under the lock.
249 if (*shared_var != 0)
251 ACE_ERROR ((LM_ERROR,
252 "Expected shared_var to be 0 under the mutex\n"));
253 *data->error_flag = 1;
256 *shared_var = 1;
258 // Sleep for a random amount of time between 0 and 2
259 // seconds. Note that it's ok to use rand() here because we
260 // are running within the critical section defined by the
261 // Thread_Mutex.
262 ACE_OS::sleep (ACE_OS::rand () % 2);
264 if (*shared_var != 1)
266 ACE_ERROR ((LM_ERROR,
267 "Expected shared_var to still be 1 after sleeping\n"));
268 *data->error_flag = 1;
271 *shared_var = 0;
273 mutex->unlock ();
275 ACE_DEBUG ((LM_DEBUG,
276 ACE_TEXT ("(%P|%t) = unlocked on iteration %d\n"),
277 i));
280 catch (const CORBA::Exception& ex)
282 ex._tao_print_exception (
283 "Unexpected exception caught in mutex_test_thread()");
284 *data->error_flag = 1;
287 return 0;
290 static int
291 test_mutex_threads (RTCORBA::RTORB_ptr rt_orb)
293 // test the RTCORBA::Mutex implementation be spawning many threads
294 // that repeatedly content for a lock. This code is based on the
295 // tests/Thread_Mutex_Test code.
297 Mutex_Test_Data test_data;
299 const u_int n_threads = MAX_THREADS;
300 int shared_var = 0;
301 int error_flag = 0;
305 RTCORBA::Mutex_ptr mutex = rt_orb->create_mutex ();
307 test_data.mutex = mutex;
308 test_data.shared_var = &shared_var;
309 test_data.error_flag = &error_flag;
311 if (ACE_Thread_Manager::instance ()->spawn_n (n_threads,
312 ACE_THR_FUNC (mutex_test_thread),
313 (void *) &test_data,
314 THR_NEW_LWP | THR_DETACHED) == -1)
315 ACE_ERROR ((LM_ERROR,
316 ACE_TEXT ("%p\n%a"),
317 ACE_TEXT ("thread create failed")));
319 // Wait for the threads to exit.
320 ACE_Thread_Manager::instance ()->wait ();
322 CORBA::release (mutex);
324 catch (const CORBA::Exception& ex)
326 ex._tao_print_exception (
327 "Unexpected exception caught in test_mutex_threads()");
328 return -1;
331 return error_flag;
334 static void *
335 mutex_test_try_lock_thread (void *args)
337 // test out try_lock() failure cases
338 Mutex_Test_Data *data = reinterpret_cast<Mutex_Test_Data *> (args);
340 RTCORBA::Mutex_ptr mutex = data->mutex;
341 CORBA::Boolean result;
345 // check that try_lock (0) returns false
346 ACE_DEBUG ((LM_DEBUG,"attempting try_lock (0) - expect failure (but no exceptions)\n"));
347 result = mutex->try_lock (0u);
349 if (result)
351 ACE_ERROR ((LM_ERROR,
352 "try_lock succeeded, but expected a failure\n"));
353 *data->error_flag = 1;
356 if (test_try_lock_flag)
358 ACE_High_Res_Timer timer;
360 // Check that try_lock (timeout) returns false (and times
361 // out)
362 ACE_DEBUG ((LM_DEBUG,
363 "attempting try_lock (5 sec) - expect failure after 5 secs (but no exceptions)\n"));
365 timer.start ();
366 result = mutex->try_lock (50000000u /*5sec*/);
367 timer.stop ();
369 if (result)
371 ACE_ERROR ((LM_ERROR,
372 "try_lock (timeout) succeeded, but expected a failure\n"));
373 *data->error_flag = 1;
376 ACE_Time_Value measured;
377 timer.elapsed_time (measured);
378 ACE_DEBUG ((LM_DEBUG,
379 "try_lock returned after %u secs, %u usecs\n",
380 measured.sec(),
381 measured.usec()));
383 if ((measured.sec() == 4 && measured.usec() >= 500000)
384 || (measured.sec() == 5 && measured.usec() <= 500000))
385 /* success */;
386 else
388 ACE_ERROR ((LM_ERROR,
389 "try_lock timed out not as expected\n"));
390 *data->error_flag = 1;
394 catch (const CORBA::Exception& ex)
396 ex._tao_print_exception (
397 "Unexpected exception caught in mutex_test_try_lock_thread()");
398 *data->error_flag = 1;
401 return 0;
404 static int
405 test_mutex_try_lock (RTCORBA::RTORB_ptr rt_orb)
407 Mutex_Test_Data test_data;
408 CORBA::Boolean result;
410 int shared_var = 0;
411 int error_flag = 0;
415 RTCORBA::Mutex_ptr mutex = rt_orb->create_mutex ();
417 // Test out try_lock and keep the lock so that the spawned task
418 // can test out try_lock failure cases
419 result = mutex->try_lock (0u);
420 if (!result)
421 ACE_ERROR_RETURN ((LM_ERROR,
422 "try_lock failed\n"),
423 -1);
425 test_data.mutex = mutex;
426 test_data.shared_var = &shared_var;
427 test_data.error_flag = &error_flag;
429 ACE_DEBUG ((LM_DEBUG,
430 "Spawning the test thread\n"));
431 if (ACE_Thread_Manager::instance ()->spawn (ACE_THR_FUNC (mutex_test_try_lock_thread),
432 (void *) &test_data,
433 THR_NEW_LWP | THR_DETACHED) == -1)
434 ACE_ERROR ((LM_ERROR,
435 ACE_TEXT ("%p\n%a"),
436 ACE_TEXT ("thread create failed")));
438 // Wait for the threads to exit.
439 ACE_Thread_Manager::instance ()->wait ();
441 mutex->unlock ();
443 CORBA::release (mutex);
445 catch (const CORBA::Exception& ex)
447 ex._tao_print_exception (
448 "Unexpected exception caught in test_mutex_try_lock()");
449 return -1;
452 return error_flag;
455 #endif /* ACE_HAS_THREADS */
458 ACE_TMAIN(int argc, ACE_TCHAR *argv[])
462 // ORB.
463 CORBA::ORB_var orb = CORBA::ORB_init (argc, argv);
465 // Parse arguments.
466 if (parse_args (argc, argv) != 0)
467 return -1;
469 // RTORB.
470 CORBA::Object_var object =
471 orb->resolve_initial_references ("RTORB");
472 RTCORBA::RTORB_var rt_orb = RTCORBA::RTORB::_narrow (object.in ());
473 if (check_for_nil (rt_orb.in (), "RTORB") == -1)
474 return -1;
476 ACE_DEBUG ((LM_DEBUG,
477 "Running RTCORBA Mutex unit tests\n"));
479 if (test_mutex_simple (rt_orb.in ()) != 0)
480 ACE_ERROR_RETURN ((LM_ERROR,
481 "test_mutex_simple failed\n"),
482 -1);
484 #if (TAO_HAS_NAMED_RT_MUTEXES == 1)
485 if (test_named_mutex_simple (rt_orb.in ()) != 0)
486 ACE_ERROR_RETURN ((LM_ERROR,
487 "test_named_mutex_simple failed\n"),
488 -1);
490 if (test_named_mutex_exception (rt_orb. in ()) != 0)
491 ACE_ERROR_RETURN ((LM_ERROR,
492 "test_named_mutex_exception failed\n"),
493 -1);
494 #else
495 ACE_DEBUG ((LM_DEBUG,
496 "Named RT_Mutex support is not enabled. "
497 "Skipping Named RT_Mutex tests.\n"));
498 #endif /* TAO_HAS_NAMED_RT_MUTEXES == 1 */
500 #if defined (ACE_HAS_THREADS)
502 if (test_mutex_threads (rt_orb.in ()) != 0)
503 ACE_ERROR_RETURN ((LM_ERROR,
504 "test_mutex_threads failed\n"),
505 -1);
506 else if (test_mutex_try_lock (rt_orb.in ()) != 0)
507 ACE_ERROR_RETURN ((LM_ERROR,
508 "test_mutex_try_lock failed\n"),
509 -1);
511 #endif /* ACE_HAS_THREADS */
513 ACE_DEBUG ((LM_DEBUG, "Mutex test finished\n\n"));
515 catch (const CORBA::Exception& ex)
517 ex._tao_print_exception (
518 "Unexpected exception caught in Mutex test server:");
519 return -1;
522 return 0;