Revert "Use a variable on the stack to not have a temporary in the call"
[ACE_TAO.git] / ACE / tests / Thread_Mutex_Test.cpp
blob3f72afe6db662f0dff12652faa703f21e74a392e
2 //=============================================================================
3 /**
4 * @file Thread_Mutex_Test.cpp
6 * This test illustrates the functionality of the
7 * ACE_Thread_Mutex. The test acquires and releases mutexes. No
8 * command line arguments are needed to run the test.
10 * @author Prashant Jain <pjain@cs.wustl.edu> and Douglas C. Schmidt <d.schmidt@vanderbilt.edu>
12 //=============================================================================
15 #include "test_config.h"
16 #include "ace/Thread_Manager.h"
17 #include "ace/OS_NS_sys_time.h"
18 #include "ace/OS_NS_time.h"
19 #include "ace/OS_NS_unistd.h"
22 #if defined (ACE_HAS_THREADS)
24 #include "ace/Guard_T.h"
26 // For all platforms except for Windows use the ACE_Thread_Mutex.
27 // Since Windows only supports timed process mutexes and not
28 // timed thread mutexes, use ACE_Process_Mutex.
29 #if defined (ACE_HAS_WTHREADS)
30 # include "ace/Process_Mutex.h"
31 typedef ACE_Process_Mutex ACE_TEST_MUTEX;
32 #else
33 # include "ace/Thread_Mutex.h"
34 using ACE_TEST_MUTEX = ACE_Thread_Mutex;
35 #endif
37 #if !defined (ACE_HAS_MUTEX_TIMEOUTS)
38 static int reported_notsup = 0;
39 #endif /* ACE_HAS_MUTEX_TIMEOUTS */
41 static void *
42 test (void *args)
44 ACE_TEST_MUTEX *mutex = (ACE_TEST_MUTEX *) args;
45 ACE_UNUSED_ARG (mutex); // Suppress ghs warning about unused local "mutex".
46 u_int seed = (u_int) ACE_OS::time (0);
48 for (size_t i = 0; i < ACE_MAX_ITERATIONS / 2; i++)
50 int result = 0;
52 // First attempt to acquire the mutex with a timeout to verify
53 // that mutex timeouts are working.
55 ACE_DEBUG ((LM_DEBUG,
56 ACE_TEXT ("(%P|%t) = trying timed acquire on ")
57 ACE_TEXT ("iteration %d\n"),
58 i));
60 ACE_Time_Value delta (1, 0); // One second timeout
61 ACE_Time_Value timeout = ACE_OS::gettimeofday ();
62 timeout += delta; // Must pass absolute time to acquire().
64 if (mutex->acquire (timeout) != 0)
66 if (errno == ETIME)
67 ACE_DEBUG ((LM_DEBUG,
68 ACE_TEXT ("(%P|%t) = mutex acquisition ")
69 ACE_TEXT ("timed out\n")));
70 else if (errno == ENOTSUP)
72 #if !defined (ACE_HAS_MUTEX_TIMEOUTS)
73 if (!reported_notsup)
75 ACE_DEBUG ((LM_INFO,
76 ACE_TEXT ("(%P|%t) %p, but ACE_HAS_MUTEX_TIMEOUTS is not defined - Ok\n"),
77 ACE_TEXT ("mutex timed acquire")));
78 reported_notsup = 1;
80 #else
81 ACE_DEBUG ((LM_ERROR,
82 ACE_TEXT ("(%P|%t) %p - maybe ACE_HAS_MUTEX_TIMEOUTS should not be defined?\n"),
83 ACE_TEXT ("mutex timed acquire")));
84 #endif /* ACE_HAS_MUTEX_TIMEOUTS */
86 else
88 ACE_ERROR ((LM_ERROR,
89 ACE_TEXT ("(%P|%t) %p\n%a"),
90 ACE_TEXT ("mutex timeout failed\n")));
91 return 0;
94 else
96 result = mutex->release ();
97 ACE_TEST_ASSERT (result == 0);
100 // Now try the standard mutex.
102 ACE_DEBUG ((LM_DEBUG,
103 ACE_TEXT ("(%P|%t) = trying to acquire on iteration %d\n"),
104 i));
105 result = mutex->acquire ();
106 ACE_TEST_ASSERT (result == 0);
107 ACE_DEBUG ((LM_DEBUG,
108 ACE_TEXT ("(%P|%t) = acquired on iteration %d\n"),
109 i));
111 // Sleep for a random amount of time between 0 and 2 seconds.
112 // Note that it's ok to use rand() here because we are running
113 // within the critical section defined by the Thread_Mutex.
114 ACE_OS::sleep (ACE_OS::rand_r (&seed) % 2);
116 result = mutex->release ();
117 ACE_TEST_ASSERT (result == 0);
118 ACE_DEBUG ((LM_DEBUG,
119 ACE_TEXT ("(%P|%t) = released on iteration %d\n"),
120 i));
122 // FUZZ: disable check_for_ACE_Guard
123 // Basic ACE_Guard usage - automatically acquire the mutex on
124 // guard construction and automatically release it on
125 // destruction.
127 // Construct an ACE_Guard to implicitly acquire the mutex.
128 ACE_Guard<ACE_TEST_MUTEX> guard (*mutex);
129 ACE_TEST_ASSERT (guard.locked () != 0);
131 // Perform some operation which might exit the current scope
132 // prematurely, e.g. by returning or throwing an exception.
133 // ...
135 // ACE_Guard object is destroyed when exiting scope and guard
136 // destructor automatically releases mutex.
139 // Use an ACE_Guard to automatically acquire a mutex, but release
140 // the mutex early.
142 // Construct an ACE_Guard to implicitly acquire the mutex.
143 ACE_Guard<ACE_TEST_MUTEX> guard (*mutex);
144 ACE_TEST_ASSERT (guard.locked () != 0);
146 // Perform some operation which might exit the current scope
147 // prematurely, e.g. by returning or throwing an exception.
148 // ...
150 // Release the mutex since we no longer need it.
151 guard.release ();
152 ACE_TEST_ASSERT (guard.locked () == 0);
154 // Do something else which does not require the mutex to be locked.
155 // ...
157 // ACE_Guard object's destructor will not release the mutex.
160 // Use an ACE_Guard to automatically acquire a mutex, but
161 // relinquish ownership of the lock so that the mutex is not
162 // automatically released on guard destruction. This is useful
163 // when an operation might not release the mutex in some
164 // conditions, in which case responsibility for releasing it is
165 // passed to someone else.
167 // Construct an ACE_Guard to implicitly acquire the mutex.
168 ACE_Guard<ACE_TEST_MUTEX> guard (*mutex);
169 ACE_TEST_ASSERT (guard.locked () != 0);
171 // Perform some operation which might exit the current scope
172 // prematurely, e.g. by returning or throwing an exception.
173 // ...
175 // Relinquish ownership of the mutex lock. Someone else must
176 // now release it.
177 guard.disown ();
178 ACE_TEST_ASSERT (guard.locked () == 0);
180 // ACE_Guard object's destructor will not release the mutex.
182 // We are now responsible for releasing the mutex.
183 result = mutex->release ();
184 ACE_TEST_ASSERT (result == 0);
186 // Construct an ACE_Guard without automatically acquiring the lock.
188 // Construct an ACE_Guard object without automatically
189 // acquiring the mutex or taking ownership of an existing
190 // lock. The third parameter tells the guard that the mutex
191 // has not been locked.
192 ACE_Guard<ACE_TEST_MUTEX> guard (*mutex, 0, 0);
193 ACE_TEST_ASSERT (guard.locked () == 0);
195 // Conditionally acquire the mutex.
196 if (i % 2 == 0)
198 guard.acquire ();
199 ACE_TEST_ASSERT (guard.locked () != 0);
202 // Perform some operation that might exit the current scope
203 // prematurely, e.g. by returning or throwing an exception.
204 // ...
206 // ACE_Guard object is destroyed when exiting scope and guard
207 // destructor automatically releases if it was acquired above.
210 // Use an ACE_Guard to take ownership of a previously acquired
211 // mutex.
212 timeout = ACE_OS::gettimeofday ();
213 timeout += delta; // Must pass absolute time to acquire().
214 if (mutex->acquire (timeout) == 0)
216 // Construct an ACE_Guard object without automatically
217 // acquiring the mutex, but instead take ownership of the
218 // existing lock. The third parameter tells the guard that
219 // the mutex has already been locked.
220 ACE_Guard<ACE_TEST_MUTEX> guard (*mutex, 0, 1);
221 ACE_TEST_ASSERT (guard.locked () != 0);
223 // Perform some operation which might exit the current scope
224 // prematurely, e.g. by returning or throwing an exception.
225 // ...
227 // ACE_Guard object is destroyed when exiting scope and guard
228 // destructor automatically releases mutex.
230 // FUZZ: enable check_for_ACE_Guard
233 return 0;
235 #endif /* ACE_HAS_THREADS */
237 static void
238 spawn ()
240 #if defined (ACE_HAS_THREADS)
241 ACE_TEST_MUTEX mutex;
243 const u_int n_threads = ACE_MAX_THREADS;
245 if (ACE_Thread_Manager::instance ()->spawn_n (n_threads,
246 ACE_THR_FUNC (test),
247 (void *) &mutex,
248 THR_NEW_LWP | THR_DETACHED) == -1)
249 ACE_ERROR ((LM_ERROR,
250 ACE_TEXT ("%p\n%a"),
251 ACE_TEXT ("thread create failed")));
253 // Wait for the threads to exit.
254 ACE_Thread_Manager::instance ()->wait ();
256 #else
257 ACE_ERROR ((LM_INFO,
258 ACE_TEXT ("threads not supported on this platform\n")));
259 #endif /* ACE_HAS_THREADS */
263 run_main (int, ACE_TCHAR *[])
265 ACE_START_TEST (ACE_TEXT ("Thread_Mutex_Test"));
267 spawn ();
269 ACE_END_TEST;
270 return 0;