2 //=============================================================================
4 * @file Process_Semaphore_Test.cpp
6 * Tests an ACE Semaphore shared between multiple child processes.
8 * @author Martin Corino <mcorino@remedy.nl>
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"
22 # include "ace/Process_Semaphore.h"
24 #include "ace/Get_Opt.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.
40 print_usage_and_die ()
43 ACE_TEXT ("usage: %n [-i #iterations] [-c (child process)]\n")));
47 // Parse the command-line arguments and set options.
49 parse_args (int argc
, ACE_TCHAR
*argv
[])
51 ACE_Get_Opt
get_opt (argc
, argv
, ACE_TEXT ("i:c"));
55 while ((c
= get_opt ()) != -1)
59 iterations
= ACE_OS::atoi (get_opt
.opt_arg ());
65 print_usage_and_die ();
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
));
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
));
83 // Make sure the constructor succeeded
84 ACE_TEST_ASSERT (ACE_LOG_MSG
->op_status () == 0);
87 ACE_TEXT ("(%P) Begin ping-pong\n")));
91 for (int i
=0; i
<iterations
;++i
)
95 if (sema_pong
.acquire ())
97 ACE_TEXT ("(%P) Failed acquiring pong\n")));
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")));
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
);
117 ACE_DEBUG ((LM_ERROR
,
118 ACE_TEXT ("(%P) Acquired pong without release()\n")));
120 sema_ping
.release (); // release waiting parent before timeout
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")));
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")));
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")));
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"));
168 ACE_TEXT ("fork is not supported on this platform\n")));
172 parse_args (argc
, argv
);
174 // Child process code.
177 ACE_START_TEST (ACE_TEXT ("Process_Semaphore_Test-child"));
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");
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"),
201 // Spawn a child process that will contend for the
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"),
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"),
223 ACE_ERROR ((LM_ERROR
,
224 ACE_TEXT ("Child %d finished with status %d\n"),
225 child
.getpid (), child_status
));
229 #endif /* ! ACE_LACKS_FORK */