diff options
Diffstat (limited to 'ACE/tests/Process_Semaphore_Test.cpp')
-rw-r--r-- | ACE/tests/Process_Semaphore_Test.cpp | 238 |
1 files changed, 238 insertions, 0 deletions
diff --git a/ACE/tests/Process_Semaphore_Test.cpp b/ACE/tests/Process_Semaphore_Test.cpp new file mode 100644 index 00000000000..42053baa5fd --- /dev/null +++ b/ACE/tests/Process_Semaphore_Test.cpp @@ -0,0 +1,238 @@ + +//============================================================================= +/** + * @file Process_Semaphore_Test.cpp + * + * $Id$ + * + * Tests an ACE Semaphore shared between multiple child processes. + * + * + * @author Martin Corino <mcorino@remedy.nl> + */ +//============================================================================= + + +#include "test_config.h" +#include "ace/Mutex.h" +#include "ace/Process.h" +#if defined (ACE_WIN32) || \ + defined (ACE_USES_FIFO_SEM) || \ + (defined (ACE_HAS_POSIX_SEM) && !defined (ACE_LACKS_NAMED_POSIX_SEM)) +# include "ace/Time_Value.h" +# include "ace/OS_NS_sys_time.h" +# include "ace/Semaphore.h" +#else +# include "ace/Process_Semaphore.h" +#endif +#include "ace/Get_Opt.h" +#include "ace/ACE.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_string.h" +#include "ace/os_include/os_dirent.h" +#include "ace/OS_NS_stdlib.h" +#include "ace/SString.h" + + + +#if !defined (ACE_LACKS_FORK) +static int iterations = 10; +static int child_process = 0; +static const char *sema_ping_name = "ACE_Ping_Semaphore"; +static const char *sema_pong_name = "ACE_Pong_Semaphore"; + +// Explain usage and exit. +static void +print_usage_and_die (void) +{ + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("usage: %n [-i #iterations] [-c (child process)]\n"))); + ACE_OS::exit (1); +} + +// Parse the command-line arguments and set options. +static void +parse_args (int argc, ACE_TCHAR *argv[]) +{ + ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("i:c")); + + int c; + + while ((c = get_opt ()) != -1) + switch (c) + { + case 'i': + iterations = ACE_OS::atoi (get_opt.opt_arg ()); + break; + case 'c': + child_process = 1; + break; + default: + print_usage_and_die (); + break; + } +} + +static void +acquire_release (void) +{ +#if defined (ACE_WIN32) || \ + defined (ACE_USES_FIFO_SEM) || \ + (defined (ACE_HAS_POSIX_SEM) && !defined (ACE_LACKS_NAMED_POSIX_SEM)) + ACE_Semaphore sema_ping (0, USYNC_PROCESS, ACE_TEXT_CHAR_TO_TCHAR (sema_ping_name)); + ACE_Semaphore sema_pong (0, USYNC_PROCESS, ACE_TEXT_CHAR_TO_TCHAR (sema_pong_name)); +#else + ACE_Process_Semaphore sema_ping (0, ACE_TEXT_CHAR_TO_TCHAR (sema_ping_name)); + ACE_Process_Semaphore sema_pong (0, ACE_TEXT_CHAR_TO_TCHAR (sema_pong_name)); +#endif + + // Make sure the constructor succeeded + ACE_TEST_ASSERT (ACE_LOG_MSG->op_status () == 0); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P) Begin ping-pong\n"))); + + if (child_process) + { + for (int i=0; i<iterations ;++i) + { + sema_ping.release (); + + if (sema_pong.acquire ()) + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("(%P) Failed acquiring pong\n"))); + else + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P) Pong\n"))); + } + +#if defined (ACE_WIN32) || \ + defined (ACE_USES_FIFO_SEM) || \ + (defined (ACE_HAS_POSIX_SEM) && defined (ACE_HAS_POSIX_SEM_TIMEOUT) && \ + !defined (ACE_LACKS_NAMED_POSIX_SEM)) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P) Testing timeouts\n"))); + + // test timed wait + ACE_Time_Value wait = ACE_OS::gettimeofday (); + wait.sec (wait.sec () + 3); // timeout in 3 secs + + if (sema_pong.acquire (wait)) + ACE_TEST_ASSERT(errno == ETIME); + else + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("(%P) Acquired pong without release()\n"))); + + sema_ping.release (); // release waiting parent before timeout +#endif + } + else + { + for (int i=0; i<iterations ;++i) + { + if (sema_ping.acquire ()) + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("(%P) Failed acquiring ping\n"))); + else + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P) Ping\n"))); + + sema_pong.release (); + } + +#if defined (ACE_WIN32) || \ + defined (ACE_USES_FIFO_SEM) || \ + (defined (ACE_HAS_POSIX_SEM) && defined (ACE_HAS_POSIX_SEM_TIMEOUT) && \ + !defined (ACE_LACKS_NAMED_POSIX_SEM)) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P) Testing timeouts\n"))); + + // test timed wait + ACE_Time_Value wait = ACE_OS::gettimeofday (); + wait.sec (wait.sec () + 10); // timeout in 10 secs + + if (sema_ping.acquire (wait)) + { + ACE_TEST_ASSERT(errno == ETIME); + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("(%P) Acquiring pong timed out\n"))); + } +#endif + } +} +#endif /* ! ACE_LACKS_FORK */ + +int +run_main (int argc, ACE_TCHAR *argv[]) +{ +#if defined (ACE_LACKS_FORK) + ACE_UNUSED_ARG (argc); + ACE_UNUSED_ARG (argv); + + ACE_START_TEST (ACE_TEXT ("Process_Semaphore_Test")); + ACE_ERROR ((LM_INFO, + ACE_TEXT ("fork is not supported on this platform\n"))); + ACE_END_TEST; +#else + + parse_args (argc, argv); + + // Child process code. + if (child_process) + { + ACE_START_TEST (ACE_TEXT ("Process_Semaphore_Test-child")); + acquire_release (); + ACE_END_LOG; + } + else + { + ACE_START_TEST (ACE_TEXT ("Process_Semaphore_Test")); + + ACE_TString exe_sub_dir; + const char *subdir_env = ACE_OS::getenv ("ACE_EXE_SUB_DIR"); + if (subdir_env) + { + exe_sub_dir = ACE_TEXT_CHAR_TO_TCHAR (subdir_env); + exe_sub_dir += ACE_DIRECTORY_SEPARATOR_STR; + } + + ACE_Process_Options options; + options.command_line (ACE_TEXT (".") ACE_DIRECTORY_SEPARATOR_STR + ACE_TEXT ("%sProcess_Semaphore_Test") + ACE_PLATFORM_EXE_SUFFIX + ACE_TEXT (" -c -i %d"), + exe_sub_dir.c_str(), + iterations); + + // Spawn a child process that will contend for the + // lock. + ACE_Process child; + + // Spawn the child process. + int result = child.spawn (options); + ACE_TEST_ASSERT (result != -1); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Parent spawned child process with pid = %d.\n"), + child.getpid ())); + + // start test + acquire_release (); + + ACE_exitcode child_status; + // Wait for the child processes we created to exit. + ACE_TEST_ASSERT (child.wait (&child_status) != -1); + if (child_status == 0) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Child %d finished ok\n"), + child.getpid ())); + else + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("Child %d finished with status %d\n"), + child.getpid (), child_status)); + + ACE_END_TEST; + } +#endif /* ! ACE_LACKS_FORK */ + + return 0; +} |