2 //=============================================================================
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
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
;
48 ACE_Token_Proxy
*token1_
;
49 ACE_Token_Proxy
*token2_
;
50 const ACE_TCHAR
*collection_name_
;
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_
));
62 ACE_TEXT ("(%t) new thread.\n")));
63 thread_start
->wait ();
68 if (collection
.acquire () == -1)
70 if (ACE_OS::last_error () == EDEADLK
)
73 ACE_TEXT ("deadlock detected in acquire")));
77 ACE_TEXT ("(%t) %p acquire failed\n"),
78 ACE_TEXT ("run_thread")));
82 ACE_TEST_ASSERT ((TOKEN_INVARIANTS::instance ()->acquired (tp
->token1_
) == 1) ||
83 (TOKEN_INVARIANTS::instance ()->acquired (tp
->token2_
) == 1));
86 ACE_TEXT ("(%t) %s acquired.\n"),
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
)
97 ACE_TEXT ("deadlock detected")));
100 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("(%t) %p renew failed\n"),
101 ACE_TEXT ("run_thread")));
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 ()));
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")));
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")));
138 run_test (ACE_Token_Proxy
*A
,
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");
152 tp2
.collection_name_
= ACE_TEXT ("A and Writer");
156 tp3
.collection_name_
= ACE_TEXT ("B and Reader");
160 // Spawn off three threads.
161 ACE_Thread_Manager
*mgr
= ACE_Thread_Manager::instance ();
163 if (mgr
->spawn (ACE_THR_FUNC (run_thread
),
166 ACE_ERROR_RETURN ((LM_DEBUG
,
168 ACE_TEXT ("spawn 1 failed")),
171 if (mgr
->spawn (ACE_THR_FUNC (run_thread
),
174 ACE_ERROR_RETURN ((LM_DEBUG
,
176 ACE_TEXT ("spawn 2 failed")),
179 if (mgr
->spawn (ACE_THR_FUNC (run_thread
),
182 ACE_ERROR_RETURN ((LM_DEBUG
,
184 ACE_TEXT ("spawn 3 failed")), -1);
186 // Wait for all threads to exit.
189 ACE_DEBUG ((LM_DEBUG
,
190 ACE_TEXT ("Test finished.\n")));
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;
204 ACE_Local_Mutex (ACE_TEXT ("L Mutex A"), 0, 0),
207 ACE_Local_Mutex (ACE_TEXT ("L Mutex B"), 0, 0),
210 ACE_Local_RLock (ACE_TEXT ("L Reader Lock"), 0, 0),
213 ACE_Local_WLock (ACE_TEXT ("L Writer Lock"), 0, 0),
215 ACE_NEW_RETURN (thread_start
,
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
);
229 ACE_ERROR ((LM_ERROR
,
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"),
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.
264 ACE_DEBUG ((LM_DEBUG
,
265 ACE_TEXT ("Using Token Server on %s at port %d.\n"),
268 ACE_Remote_Mutex::set_server_address (ACE_INET_Addr (server_port
,
277 ACE_Remote_Mutex (ACE_TEXT ("R Mutex A"), 0, 1),
280 ACE_Remote_Mutex (ACE_TEXT ("R Mutex B"), 0, 1),
283 ACE_Remote_RLock (ACE_TEXT ("R Reader Lock"), 0, 1),
286 ACE_Remote_WLock (ACE_TEXT ("R Writer Lock"), 0, 1),
289 run_test (A
, B
, R
, W
);
291 // Wait for the server to finish.
294 // Kill the token server.
295 if (new_process
.terminate () == -1)
296 ACE_ERROR_RETURN ((LM_ERROR
,
297 ACE_TEXT ("Kill failed.\n")),
309 ACE_DEBUG ((LM_DEBUG
,
310 ACE_TEXT ("(%t) main thread exiting.\n")));
313 ACE_TEXT ("ACE must be compiled with -DACE_HAS_TOKENS_LIBRARY to run this test\n")));
314 #endif /* ACE_HAS_TOKENS_LIBRARY */
317 ACE_TEXT ("threads not supported on this platform\n")));
318 #endif /* ACE_HAS_THREADS */