2 //=============================================================================
4 * @file Process_Manual_Event_Test.cpp
6 * This test verifies the functionality of the <ACE_Manual_Event>
7 * process-shared implementation.
9 * @author Martin Corino <mcorino@remedy.nl>
11 //=============================================================================
13 #include "test_config.h"
14 #include "ace/Process.h"
15 #include "ace/Manual_Event.h"
16 #include "ace/Time_Value.h"
17 #include "ace/Get_Opt.h"
19 #include "ace/OS_NS_stdio.h"
20 #include "ace/OS_NS_string.h"
21 #include "ace/OS_NS_sys_time.h"
22 #include "ace/OS_NS_unistd.h"
23 #include "ace/os_include/os_dirent.h"
25 #if (!defined (ACE_LACKS_FORK) || defined (ACE_WIN32)) && \
26 (defined (ACE_WIN32) || \
27 (defined (ACE_HAS_PTHREADS) && defined (_POSIX_THREAD_PROCESS_SHARED) && \
28 !defined (ACE_LACKS_MUTEXATTR_PSHARED) && !defined (ACE_LACKS_CONDATTR_PSHARED)) || \
29 defined (ACE_USES_FIFO_SEM) || \
30 (defined (ACE_HAS_POSIX_SEM) && defined (ACE_HAS_POSIX_SEM_TIMEOUT) && !defined (ACE_LACKS_NAMED_POSIX_SEM)))
31 static int iterations
= 10;
32 static int child_process
= 0;
33 static const ACE_TCHAR
*event_ping_name
= ACE_TEXT ("ACE_Ping_Event");
34 static const ACE_TCHAR
*event_pong_name
= ACE_TEXT ("ACE_Pong_Event");
36 // Explain usage and exit.
38 print_usage_and_die ()
41 ACE_TEXT ("usage: %n [-i #iterations] [-c (child process)]\n")));
45 // Parse the command-line arguments and set options.
47 parse_args (int argc
, ACE_TCHAR
*argv
[])
49 ACE_Get_Opt
get_opt (argc
, argv
, ACE_TEXT ("i:c"));
53 while ((c
= get_opt ()) != -1)
57 iterations
= ACE_OS::atoi (get_opt
.opt_arg ());
63 print_usage_and_die ();
71 ACE_Manual_Event
event_ping (0, USYNC_PROCESS
, event_ping_name
);
72 ACE_Manual_Event
event_pong (0, USYNC_PROCESS
, event_pong_name
);
74 // Make sure the constructor succeeded
75 ACE_TEST_ASSERT (ACE_LOG_MSG
->op_status () == 0);
78 ACE_TEXT ("(%P) Begin ping-pong\n")));
83 for (i
= 0; i
< iterations
; ++i
)
87 if (event_pong
.wait ())
89 ACE_TEXT ("(%P) %p\n"),
90 ACE_TEXT ("Failed acquiring pong")));
94 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("(%P) Pong\n")));
98 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("(%P) Testing timeouts\n")));
101 ACE_Time_Value wait
= ACE_OS::gettimeofday ();
102 wait
.sec (wait
.sec () + 3); // timeout in 3 secs
104 if (event_pong
.wait (&wait
))
107 ACE_ERROR ((LM_ERROR
,
108 ACE_TEXT ("(%P) %p, but expected ETIME\n"),
109 ACE_TEXT ("event_pong.wait()")));
112 ACE_ERROR ((LM_ERROR
,
113 ACE_TEXT ("(%P) Acquired pong without release()\n")));
115 event_ping
.signal (); // release waiting parent before timeout
119 for (i
= 0; i
< iterations
; ++i
)
121 if (event_ping
.wait ())
122 ACE_ERROR ((LM_ERROR
,
123 ACE_TEXT ("(%P) %p\n"),
124 ACE_TEXT ("Failed acquiring ping")));
128 ACE_DEBUG ((LM_DEBUG
,
129 ACE_TEXT ("(%P) Ping\n")));
132 event_pong
.signal ();
135 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("(%P) Testing timeouts\n")));
138 ACE_Time_Value wait
= ACE_OS::gettimeofday ();
139 wait
.sec (wait
.sec () + 10); // timeout in 10 secs
141 if (event_ping
.wait (&wait
))
144 ACE_ERROR ((LM_ERROR
,
145 ACE_TEXT ("(%P) %p but should be ETIME\n"),
146 ACE_TEXT ("Acquire pong")));
148 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("(%P) Acquire pong timed out\n")));
152 #endif /* ! ACE_LACKS_FORK */
155 run_main (int argc
, ACE_TCHAR
*argv
[])
157 #if defined (ACE_LACKS_FORK) && !defined (ACE_WIN32)
158 ACE_UNUSED_ARG (argc
);
159 ACE_UNUSED_ARG (argv
);
161 ACE_START_TEST (ACE_TEXT ("Process_Manual_Event_Test"));
163 ACE_TEXT ("fork is not supported on this platform\n")));
165 #elif defined (ACE_WIN32) || \
166 (defined (ACE_HAS_PTHREADS) && defined (_POSIX_THREAD_PROCESS_SHARED) && \
167 !defined (ACE_LACKS_MUTEXATTR_PSHARED) && !defined (ACE_LACKS_CONDATTR_PSHARED)) || \
168 defined (ACE_USES_FIFO_SEM) || \
169 (defined (ACE_HAS_POSIX_SEM) && defined (ACE_HAS_POSIX_SEM_TIMEOUT) && !defined (ACE_LACKS_NAMED_POSIX_SEM))
171 parse_args (argc
, argv
);
173 // Child process code.
176 ACE_START_TEST (ACE_TEXT ("Process_Manual_Event_Test-child"));
183 ACE_START_TEST (ACE_TEXT ("Process_Manual_Event_Test"));
185 // The parent cleans up any remnant of past runs of this test.
186 // See Bugzilla #2662 for further info.
188 ACE_TCHAR
const * argv_0
= argc
> 0 ? argv
[0] : ACE_TEXT ("Process_Manual_Event_Test");
190 #if defined (ACE_WIN32)
191 const ACE_TCHAR
*cmdline_format
= ACE_TEXT("\"%s\" -c -i %d");
192 #elif !defined (ACE_USES_WCHAR)
193 const ACE_TCHAR
*cmdline_format
= argc
> 0 ? ACE_TEXT ("%s -c -i %d") : (ACE_TEXT (".") ACE_DIRECTORY_SEPARATOR_STR
ACE_TEXT("%s -c -i %d"));
195 const ACE_TCHAR
*cmdline_format
= argc
> 0 ? ACE_TEXT ("%s -c -i %d") : (ACE_TEXT (".") ACE_DIRECTORY_SEPARATOR_STR
ACE_TEXT("%ls -c -i %d"));
198 ACE_Process_Options options
;
199 options
.command_line (cmdline_format
,
202 // Spawn a child process that will contend for the
206 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT("Spawning <%s> <%s>\n"),
207 options
.process_name(),
208 options
.command_line_buf ()));
210 // Spawn the child process.
211 pid_t result
= child
.spawn (options
);
212 if (result
!= ACE_INVALID_PID
)
213 ACE_DEBUG ((LM_DEBUG
,
214 ACE_TEXT ("Parent spawned child process with pid = %d.\n"),
217 ACE_ERROR_RETURN ((LM_ERROR
, ACE_TEXT ("%p\n"),
218 ACE_TEXT ("spawn failed")), 1);
223 ACE_exitcode child_status
;
224 // Wait for the child processes we created to exit.
225 int wait_result
= child
.wait (&child_status
);
226 ACE_TEST_ASSERT (wait_result
!= -1);
227 if (child_status
== 0)
228 ACE_DEBUG ((LM_DEBUG
,
229 ACE_TEXT ("Child %d finished ok\n"),
232 ACE_ERROR ((LM_ERROR
,
233 ACE_TEXT ("Child %d finished with status %d\n"),
234 child
.getpid (), child_status
));
237 #else /* !ACE_LACKS_FORK */
238 ACE_UNUSED_ARG (argc
);
239 ACE_UNUSED_ARG (argv
);
241 ACE_START_TEST (ACE_TEXT ("Process_Manual_Event_Test"));
243 ACE_TEXT ("Process shared events are not supported on this platform\n")));
245 #endif /* ! ACE_LACKS_FORK */