Revert "Use a variable on the stack to not have a temporary in the call"
[ACE_TAO.git] / ACE / tests / Process_Semaphore_Test.cpp
blobaf182297bcb242e6aa5ec8367f80290202bf1780
2 //=============================================================================
3 /**
4 * @file Process_Semaphore_Test.cpp
6 * Tests an ACE Semaphore shared between multiple child processes.
8 * @author Martin Corino <mcorino@remedy.nl>
9 */
10 //=============================================================================
12 #include "test_config.h"
13 #include "ace/Mutex.h"
14 #include "ace/Process.h"
15 #if defined (ACE_WIN32) || \
16 defined (ACE_USES_FIFO_SEM) || \
17 (defined (ACE_HAS_POSIX_SEM) && !defined (ACE_LACKS_NAMED_POSIX_SEM))
18 # include "ace/Time_Value.h"
19 # include "ace/OS_NS_sys_time.h"
20 # include "ace/Semaphore.h"
21 #else
22 # include "ace/Process_Semaphore.h"
23 #endif
24 #include "ace/Get_Opt.h"
25 #include "ace/ACE.h"
26 #include "ace/OS_NS_stdio.h"
27 #include "ace/OS_NS_string.h"
28 #include "ace/os_include/os_dirent.h"
29 #include "ace/OS_NS_stdlib.h"
30 #include "ace/SString.h"
32 #if !defined (ACE_LACKS_FORK)
33 static int iterations = 10;
34 static int child_process = 0;
35 static const char *sema_ping_name = "ACE_Ping_Semaphore";
36 static const char *sema_pong_name = "ACE_Pong_Semaphore";
38 // Explain usage and exit.
39 static void
40 print_usage_and_die ()
42 ACE_DEBUG ((LM_DEBUG,
43 ACE_TEXT ("usage: %n [-i #iterations] [-c (child process)]\n")));
44 ACE_OS::exit (1);
47 // Parse the command-line arguments and set options.
48 static void
49 parse_args (int argc, ACE_TCHAR *argv[])
51 ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("i:c"));
53 int c;
55 while ((c = get_opt ()) != -1)
56 switch (c)
58 case 'i':
59 iterations = ACE_OS::atoi (get_opt.opt_arg ());
60 break;
61 case 'c':
62 child_process = 1;
63 break;
64 default:
65 print_usage_and_die ();
66 break;
70 static void
71 acquire_release ()
73 #if defined (ACE_WIN32) || \
74 defined (ACE_USES_FIFO_SEM) || \
75 (defined (ACE_HAS_POSIX_SEM) && !defined (ACE_LACKS_NAMED_POSIX_SEM))
76 ACE_Semaphore sema_ping (0, USYNC_PROCESS, ACE_TEXT_CHAR_TO_TCHAR (sema_ping_name));
77 ACE_Semaphore sema_pong (0, USYNC_PROCESS, ACE_TEXT_CHAR_TO_TCHAR (sema_pong_name));
78 #else
79 ACE_Process_Semaphore sema_ping (0, ACE_TEXT_CHAR_TO_TCHAR (sema_ping_name));
80 ACE_Process_Semaphore sema_pong (0, ACE_TEXT_CHAR_TO_TCHAR (sema_pong_name));
81 #endif
83 // Make sure the constructor succeeded
84 ACE_TEST_ASSERT (ACE_LOG_MSG->op_status () == 0);
86 ACE_DEBUG ((LM_DEBUG,
87 ACE_TEXT ("(%P) Begin ping-pong\n")));
89 if (child_process)
91 for (int i=0; i<iterations ;++i)
93 sema_ping.release ();
95 if (sema_pong.acquire ())
96 ACE_DEBUG ((LM_ERROR,
97 ACE_TEXT ("(%P) Failed acquiring pong\n")));
98 else
99 ACE_DEBUG ((LM_DEBUG,
100 ACE_TEXT ("(%P) Pong\n")));
103 #if defined (ACE_WIN32) || \
104 defined (ACE_USES_FIFO_SEM) || \
105 (defined (ACE_HAS_POSIX_SEM) && defined (ACE_HAS_POSIX_SEM_TIMEOUT) && \
106 !defined (ACE_LACKS_NAMED_POSIX_SEM))
107 ACE_DEBUG ((LM_DEBUG,
108 ACE_TEXT ("(%P) Testing timeouts\n")));
110 // test timed wait
111 ACE_Time_Value wait = ACE_OS::gettimeofday ();
112 wait.sec (wait.sec () + 3); // timeout in 3 secs
114 if (sema_pong.acquire (wait))
115 ACE_TEST_ASSERT(errno == ETIME);
116 else
117 ACE_DEBUG ((LM_ERROR,
118 ACE_TEXT ("(%P) Acquired pong without release()\n")));
120 sema_ping.release (); // release waiting parent before timeout
121 #endif
123 else
125 for (int i=0; i<iterations ;++i)
127 if (sema_ping.acquire ())
128 ACE_DEBUG ((LM_ERROR,
129 ACE_TEXT ("(%P) Failed acquiring ping\n")));
130 else
131 ACE_DEBUG ((LM_DEBUG,
132 ACE_TEXT ("(%P) Ping\n")));
134 sema_pong.release ();
137 #if defined (ACE_WIN32) || \
138 defined (ACE_USES_FIFO_SEM) || \
139 (defined (ACE_HAS_POSIX_SEM) && defined (ACE_HAS_POSIX_SEM_TIMEOUT) && \
140 !defined (ACE_LACKS_NAMED_POSIX_SEM))
141 ACE_DEBUG ((LM_DEBUG,
142 ACE_TEXT ("(%P) Testing timeouts\n")));
144 // test timed wait
145 ACE_Time_Value wait = ACE_OS::gettimeofday ();
146 wait.sec (wait.sec () + 10); // timeout in 10 secs
148 if (sema_ping.acquire (wait))
150 ACE_TEST_ASSERT(errno == ETIME);
151 ACE_DEBUG ((LM_ERROR,
152 ACE_TEXT ("(%P) Acquiring pong timed out\n")));
154 #endif
157 #endif /* ! ACE_LACKS_FORK */
160 run_main (int argc, ACE_TCHAR *argv[])
162 #if defined (ACE_LACKS_FORK)
163 ACE_UNUSED_ARG (argc);
164 ACE_UNUSED_ARG (argv);
166 ACE_START_TEST (ACE_TEXT ("Process_Semaphore_Test"));
167 ACE_ERROR ((LM_INFO,
168 ACE_TEXT ("fork is not supported on this platform\n")));
169 ACE_END_TEST;
170 #else
172 parse_args (argc, argv);
174 // Child process code.
175 if (child_process)
177 ACE_START_TEST (ACE_TEXT ("Process_Semaphore_Test-child"));
178 acquire_release ();
179 ACE_END_LOG;
181 else
183 ACE_START_TEST (ACE_TEXT ("Process_Semaphore_Test"));
185 ACE_TString exe_sub_dir;
186 const char *subdir_env = ACE_OS::getenv ("ACE_EXE_SUB_DIR");
187 if (subdir_env)
189 exe_sub_dir = ACE_TEXT_CHAR_TO_TCHAR (subdir_env);
190 exe_sub_dir += ACE_DIRECTORY_SEPARATOR_STR;
193 ACE_Process_Options options;
194 options.command_line (ACE_TEXT (".") ACE_DIRECTORY_SEPARATOR_STR
195 ACE_TEXT ("%sProcess_Semaphore_Test")
196 ACE_PLATFORM_EXE_SUFFIX
197 ACE_TEXT (" -c -i %d"),
198 exe_sub_dir.c_str(),
199 iterations);
201 // Spawn a child process that will contend for the
202 // lock.
203 ACE_Process child;
205 // Spawn the child process.
206 int result = child.spawn (options);
207 ACE_TEST_ASSERT (result != -1);
208 ACE_DEBUG ((LM_DEBUG,
209 ACE_TEXT ("Parent spawned child process with pid = %d.\n"),
210 child.getpid ()));
212 // start test
213 acquire_release ();
215 ACE_exitcode child_status;
216 // Wait for the child processes we created to exit.
217 ACE_TEST_ASSERT (child.wait (&child_status) != -1);
218 if (child_status == 0)
219 ACE_DEBUG ((LM_DEBUG,
220 ACE_TEXT ("Child %d finished ok\n"),
221 child.getpid ()));
222 else
223 ACE_ERROR ((LM_ERROR,
224 ACE_TEXT ("Child %d finished with status %d\n"),
225 child.getpid (), child_status));
227 ACE_END_TEST;
229 #endif /* ! ACE_LACKS_FORK */
231 return 0;