Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / tests / Tokens_Test.cpp
blob3c1940f1d9c2318a9b0ae42743d1dd0456db94db
2 //=============================================================================
3 /**
4 * @file Tokens_Test.cpp
6 * This application tests the ACE Token library including local
7 * and remote readers/writer and mutex locks, and token
8 * collections. This is accomplished with the ACE Token Invariant
9 * utilities that allow and application to check that
10 * readers/writer and mutex lock invariants are always satisfied.
11 * Throughout this test, ACE_TEST_ASSERTs are used in conjunction with
12 * Token Invariant operations, so that errors are reported using
13 * the ACE tests convention. This application performs a local
14 * test and then fork_execs a token server and performs the same
15 * test remotely.
17 * @author Tim Harrison <harrison@cs.wustl.edu>
19 //=============================================================================
21 #include "test_config.h"
22 #include "ace/Process.h"
23 #include "ace/Get_Opt.h"
24 #include "ace/Local_Tokens.h"
25 #include "ace/Token_Collection.h"
26 #include "ace/Remote_Tokens.h"
27 #include "ace/Thread_Manager.h"
28 #include "ace/Token_Invariants.h"
29 #include "ace/Barrier.h"
30 #include "ace/OS_NS_unistd.h"
32 #if defined (ACE_HAS_THREADS) && defined (ACE_HAS_TOKENS_LIBRARY)
34 typedef ACE_Token_Invariant_Manager TOKEN_INVARIANTS;
36 static const ACE_TCHAR *server_host = ACE_DEFAULT_SERVER_HOST;
37 static const int server_port = 23456;
39 // Synchronize starts of threads, so that they all start before one
40 // has a chance to finish and clean up the TSS objects. To avoid
41 // creating a static object, it is dynamically allocated, before
42 // spawning any threads.
43 static ACE_Barrier *thread_start;
45 struct Test_Params
47 public:
48 ACE_Token_Proxy *token1_;
49 ACE_Token_Proxy *token2_;
50 const ACE_TCHAR *collection_name_;
53 static void *
54 run_thread (void *vp)
56 Test_Params *tp = (Test_Params *) vp;
57 ACE_Token_Collection collection (1, tp->collection_name_);
58 collection.insert (*(tp->token1_));
59 collection.insert (*(tp->token2_));
61 ACE_DEBUG ((LM_DEBUG,
62 ACE_TEXT ("(%t) new thread.\n")));
63 thread_start->wait ();
65 int count = 50;
66 while (count--)
68 if (collection.acquire () == -1)
70 if (ACE_OS::last_error () == EDEADLK)
72 ACE_DEBUG ((LM_DEBUG,
73 ACE_TEXT ("deadlock detected in acquire")));
74 continue;
76 ACE_ERROR ((LM_ERROR,
77 ACE_TEXT ("(%t) %p acquire failed\n"),
78 ACE_TEXT ("run_thread")));
79 return (void *) -1;
82 ACE_TEST_ASSERT ((TOKEN_INVARIANTS::instance ()->acquired (tp->token1_) == 1) ||
83 (TOKEN_INVARIANTS::instance ()->acquired (tp->token2_) == 1));
85 ACE_DEBUG ((LM_DEBUG,
86 ACE_TEXT ("(%t) %s acquired.\n"),
87 collection.name ()));
89 TOKEN_INVARIANTS::instance ()->releasing (tp->token1_);
90 TOKEN_INVARIANTS::instance ()->releasing (tp->token2_);
92 if (collection.renew () == -1)
94 if (ACE_OS::last_error () == EDEADLK)
96 ACE_DEBUG ((LM_DEBUG,
97 ACE_TEXT ("deadlock detected")));
98 goto deadlock;
100 ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%t) %p renew failed\n"),
101 ACE_TEXT ("run_thread")));
102 return (void *) -1;
105 ACE_TEST_ASSERT (TOKEN_INVARIANTS::instance ()->acquired (tp->token1_) == 1 ||
106 TOKEN_INVARIANTS::instance ()->acquired (tp->token2_) == 1);
108 ACE_DEBUG ((LM_DEBUG,
109 ACE_TEXT ("(%t) %s renewed.\n"),
110 collection.name ()));
112 deadlock:
114 TOKEN_INVARIANTS::instance ()->releasing (tp->token1_);
115 TOKEN_INVARIANTS::instance ()->releasing (tp->token2_);
117 if (collection.release () == -1)
119 ACE_ERROR ((LM_ERROR,
120 ACE_TEXT ("(%t) %p release failed\n"),
121 ACE_TEXT ("run_thread")));
122 return (void *) -1;
125 ACE_DEBUG ((LM_DEBUG,
126 ACE_TEXT ("(%t) %s released.\n"),
127 collection.name ()));
131 ACE_DEBUG ((LM_DEBUG,
132 ACE_TEXT ("(%t) thread finished.\n")));
134 return 0;
137 static int
138 run_test (ACE_Token_Proxy *A,
139 ACE_Token_Proxy *B,
140 ACE_Token_Proxy *R,
141 ACE_Token_Proxy *W)
143 // Parameters to be passed to the threads.
144 Test_Params tp1, tp2, tp3;
146 // tp1 and tp2 can run concurrently. Neither tp1 or tp3 can run
147 // when tp2 is running.
148 tp1.collection_name_ = ACE_TEXT ("A and Reader");
149 tp1.token1_ = A;
150 tp1.token2_ = R;
152 tp2.collection_name_ = ACE_TEXT ("A and Writer");
153 tp2.token1_ = A;
154 tp2.token2_ = W;
156 tp3.collection_name_ = ACE_TEXT ("B and Reader");
157 tp3.token1_ = B;
158 tp3.token2_ = R;
160 // Spawn off three threads.
161 ACE_Thread_Manager *mgr = ACE_Thread_Manager::instance ();
163 if (mgr->spawn (ACE_THR_FUNC (run_thread),
164 (void *) &tp1,
165 THR_BOUND) == -1)
166 ACE_ERROR_RETURN ((LM_DEBUG,
167 ACE_TEXT ("%p\n"),
168 ACE_TEXT ("spawn 1 failed")),
169 -1);
171 if (mgr->spawn (ACE_THR_FUNC (run_thread),
172 (void *) &tp2,
173 THR_BOUND) == -1)
174 ACE_ERROR_RETURN ((LM_DEBUG,
175 ACE_TEXT ("%p\n"),
176 ACE_TEXT ("spawn 2 failed")),
177 -1);
179 if (mgr->spawn (ACE_THR_FUNC (run_thread),
180 (void *) &tp3,
181 THR_BOUND) == -1)
182 ACE_ERROR_RETURN ((LM_DEBUG,
183 ACE_TEXT ("%p\n"),
184 ACE_TEXT ("spawn 3 failed")), -1);
186 // Wait for all threads to exit.
187 mgr->wait ();
189 ACE_DEBUG ((LM_DEBUG,
190 ACE_TEXT ("Test finished.\n")));
191 return 0;
193 #endif /* ACE_HAS_THREADS && ACE_HAS_TOKENS_LIBRARY */
196 run_main (int, ACE_TCHAR *[])
198 ACE_START_TEST (ACE_TEXT ("Tokens_Test"));
199 #if defined (ACE_HAS_THREADS)
200 #if defined (ACE_HAS_TOKENS_LIBRARY)
201 ACE_Token_Proxy *A = 0, *B = 0, *R = 0, *W = 0;
203 ACE_NEW_RETURN (A,
204 ACE_Local_Mutex (ACE_TEXT ("L Mutex A"), 0, 0),
205 -1);
206 ACE_NEW_RETURN (B,
207 ACE_Local_Mutex (ACE_TEXT ("L Mutex B"), 0, 0),
208 -1);
209 ACE_NEW_RETURN (R,
210 ACE_Local_RLock (ACE_TEXT ("L Reader Lock"), 0, 0),
211 -1);
212 ACE_NEW_RETURN (W,
213 ACE_Local_WLock (ACE_TEXT ("L Writer Lock"), 0, 0),
214 -1);
215 ACE_NEW_RETURN (thread_start,
216 ACE_Barrier (3),
217 -1);
219 run_test (A, B, R, W);
221 const ACE_TCHAR *token_exe =
222 ACE_TEXT ("..") ACE_DIRECTORY_SEPARATOR_STR
223 ACE_TEXT ("netsvcs") ACE_DIRECTORY_SEPARATOR_STR
224 ACE_TEXT ("servers") ACE_DIRECTORY_SEPARATOR_STR
225 ACE_TEXT ("main") ACE_PLATFORM_EXE_SUFFIX;
227 int status = ACE_OS::access (token_exe, F_OK);
228 if (status == -1)
229 ACE_ERROR ((LM_ERROR,
230 ACE_TEXT ("%p\n"),
231 token_exe));
232 else
234 const ACE_TCHAR *cl =
235 ACE_TEXT ("..") ACE_DIRECTORY_SEPARATOR_STR
236 ACE_TEXT ("netsvcs") ACE_DIRECTORY_SEPARATOR_STR
237 ACE_TEXT ("servers") ACE_DIRECTORY_SEPARATOR_STR
238 ACE_TEXT ("main") ACE_PLATFORM_EXE_SUFFIX
239 ACE_TEXT (" -f ") ACE_PLATFORM
240 ACE_TEXT ("tokens.conf");
242 ACE_Process_Options options;
243 options.command_line (cl);
245 ACE_DEBUG ((LM_DEBUG,
246 ACE_TEXT ("Forking Token Service.\n")));
248 // Start up the token server for the remote test.
249 ACE_Process new_process;
250 if (new_process.spawn (options) == -1)
251 ACE_ERROR ((LM_ERROR,
252 ACE_TEXT ("%n; %p (%s), will not run remote test.\n"),
253 ACE_TEXT ("Server fork failed"),
254 cl));
255 else
257 ACE_DEBUG ((LM_DEBUG,
258 ACE_TEXT ("Server forked with pid = %d.\n"),
259 new_process.getpid ()));
261 // Wait for the server to start.
262 ACE_OS::sleep (3);
264 ACE_DEBUG ((LM_DEBUG,
265 ACE_TEXT ("Using Token Server on %s at port %d.\n"),
266 server_host,
267 server_port));
268 ACE_Remote_Mutex::set_server_address (ACE_INET_Addr (server_port,
269 server_host));
271 delete A;
272 delete B;
273 delete R;
274 delete W;
276 ACE_NEW_RETURN (A,
277 ACE_Remote_Mutex (ACE_TEXT ("R Mutex A"), 0, 1),
278 -1);
279 ACE_NEW_RETURN (B,
280 ACE_Remote_Mutex (ACE_TEXT ("R Mutex B"), 0, 1),
281 -1);
282 ACE_NEW_RETURN (R,
283 ACE_Remote_RLock (ACE_TEXT ("R Reader Lock"), 0, 1),
284 -1);
285 ACE_NEW_RETURN (W,
286 ACE_Remote_WLock (ACE_TEXT ("R Writer Lock"), 0, 1),
287 -1);
289 run_test (A, B, R, W);
291 // Wait for the server to finish.
292 ACE_OS::sleep (3);
294 // Kill the token server.
295 if (new_process.terminate () == -1)
296 ACE_ERROR_RETURN ((LM_ERROR,
297 ACE_TEXT ("Kill failed.\n")),
298 -1);
301 delete thread_start;
302 thread_start = 0;
303 delete A;
304 delete B;
305 delete R;
306 delete W;
309 ACE_DEBUG ((LM_DEBUG,
310 ACE_TEXT ("(%t) main thread exiting.\n")));
311 #else
312 ACE_ERROR ((LM_INFO,
313 ACE_TEXT ("ACE must be compiled with -DACE_HAS_TOKENS_LIBRARY to run this test\n")));
314 #endif /* ACE_HAS_TOKENS_LIBRARY */
315 #else
316 ACE_ERROR ((LM_INFO,
317 ACE_TEXT ("threads not supported on this platform\n")));
318 #endif /* ACE_HAS_THREADS */
319 ACE_END_TEST;
320 return 0;