summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormcorino <mcorino@users.noreply.github.com>2005-06-24 10:34:26 +0000
committermcorino <mcorino@users.noreply.github.com>2005-06-24 10:34:26 +0000
commit7c6148dca9d50acae7e9b66146bcfcb8f4efee13 (patch)
tree7b661b078ece25e4ddf38ce3c4d64d71e28f3880
parentd3b8c4aa5c54d0d014210f4c4fa3ac525a352c6a (diff)
downloadATCD-7c6148dca9d50acae7e9b66146bcfcb8f4efee13.tar.gz
ChangeLogTag: Fri Jun 23 10:20:12 UTC 2005 Martin Corino <mcorino@remedy.nl>
-rw-r--r--ChangeLog17
-rw-r--r--ace/OS_NS_Thread.inl11
-rw-r--r--tests/Auto_Event_Test.cpp226
-rw-r--r--tests/Manual_Event_Test.cpp205
-rw-r--r--tests/Process_Manual_Event_Test.cpp209
-rw-r--r--tests/Process_Semaphore_Test.cpp219
-rw-r--r--tests/Semaphore_Test.cpp8
-rw-r--r--tests/run_test.lst3
-rw-r--r--tests/tests.mpc28
9 files changed, 919 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index b52de365092..485f47bf452 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+Fri Jun 23 10:20:12 UTC 2005 Martin Corino <mcorino@remedy.nl>
+
+ * ace/OS_NS_Thread.inl:
+ Made sure ETIME is always returned on timeouts of
+ ACE_OS::sema_timedwait and not ETIMEDOUT.
+
+ * tests/Semaphore_Test.cpp:
+ Extended platform coverage of timeout tests.
+
+ * tests/Auto_Event_Test.cpp:
+ * tests/Manual_Event_Test.cpp:
+ * tests/Process_Manual_Event_Test.cpp:
+ * tests/Process_Semaphore_Test.cpp:
+ * tests/run_test.lst:
+ * tests/tests.mpc:
+ Added new tests.
+
Fri Jun 23 09:17:12 UTC 2005 Martin Corino <mcorino@remedy.nl>
* tests/INET_Addr_Test_IPV6.cpp:
diff --git a/ace/OS_NS_Thread.inl b/ace/OS_NS_Thread.inl
index ed9a00e1f6f..27080c9a2d5 100644
--- a/ace/OS_NS_Thread.inl
+++ b/ace/OS_NS_Thread.inl
@@ -2121,9 +2121,13 @@ ACE_OS::sema_wait (ACE_sema_t *s, ACE_Time_Value &tv)
ACE_OS_TRACE ("ACE_OS::sema_wait");
# if defined (ACE_HAS_POSIX_SEM)
# if defined (ACE_HAS_POSIX_SEM_TIMEOUT)
+ int rc;
timespec_t ts;
ts = tv; // Calls ACE_Time_Value::operator timespec_t().
- ACE_OSCALL_RETURN (::sem_timedwait (s->sema_, &ts), int, -1);
+ ACE_OSCALL (::sem_timedwait (s->sema_, &ts), int, -1, rc);
+ if (rc == -1 && errno == ETIMEDOUT)
+ errno = ETIME; /* POSIX returns ETIMEDOUT but we need ETIME */
+ return rc;
# else
ACE_UNUSED_ARG (s);
ACE_UNUSED_ARG (tv);
@@ -2144,8 +2148,9 @@ ACE_OS::sema_wait (ACE_sema_t *s, ACE_Time_Value &tv)
if ((rc = ACE_OS::select (ACE_Handle_Set::MAXSIZE, fds_, 0, 0, timeout)) != 1)
{
if (rc == 0)
- // make sure errno is set right (select() sets ETIME)
- errno = ETIMEDOUT;
+ errno = ETIME;
+ else if (rc == -1 && errno == EINTR)
+ errno = ETIME;
return (-1);
}
diff --git a/tests/Auto_Event_Test.cpp b/tests/Auto_Event_Test.cpp
new file mode 100644
index 00000000000..a31b8a9f6a1
--- /dev/null
+++ b/tests/Auto_Event_Test.cpp
@@ -0,0 +1,226 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// tests
+//
+// = FILENAME
+// Auto_Event Test
+//
+// = DESCRIPTION
+// This test verifies the functionality of the <ACE_Auto_Event>
+// implementation.
+//
+// = AUTHOR
+// Martin Corino <mcorino@remedy.nl>
+//
+// ============================================================================
+
+#include "test_config.h"
+#include "ace/Auto_Event.h"
+#include "ace/Thread.h"
+#include "ace/Thread_Manager.h"
+#include "ace/Get_Opt.h"
+#include "ace/OS_NS_sys_time.h"
+#include "ace/OS_NS_time.h"
+#include "ace/OS_NS_unistd.h"
+
+ACE_RCSID(tests, Auto_Event_Test, "$Id$")
+
+// msec that times are allowed to differ before test fails.
+#if defined (ACE_HAS_HI_RES_TIMER) || defined (ACE_HAS_AIX_HI_RES_TIMER) || \
+ defined (ACE_HAS_PENTIUM) || defined (ACE_HAS_ALPHA_TIMER) || \
+ defined (ACE_HAS_POWERPC_TIMER)
+# define ACE_ALLOWED_SLACK 100
+#else /* don't have a high-res timer */
+# define ACE_ALLOWED_SLACK 1100
+#endif /* don't have a high-res timer */
+
+// Test results, 'success' is 0
+static int test_result = 0;
+
+#if defined (ACE_HAS_THREADS)
+
+// Event used in the tests. Start it "unsignalled" (i.e., its initial
+// state is 0).
+static ACE_Auto_Event evt ((unsigned int) 0);
+
+// Default number of iterations.
+static int n_iterations = 10;
+
+// Number of worker threads.
+static size_t n_workers = 10;
+
+// Number of timeouts.
+static size_t timeouts = 0;
+
+// Number of times to call test_timeout ().
+static size_t test_timeout_count = 3;
+
+// Tests the amount of time spent in a timed wait.
+static int
+test_timeout (void)
+{
+ int status = 0;
+
+ // milliseconds...
+ long msecs_expected;
+ long msecs_waited;
+ long msecs_diff;
+
+ // Wait a little longer each time
+ static long wait_secs = 3;
+
+ ACE_Time_Value wait = ACE_OS::gettimeofday ();
+
+ ACE_Time_Value begin = wait;
+
+ wait.sec (wait.sec () + wait_secs);
+
+ if (evt.wait (&wait) == -1)
+ ACE_ASSERT (errno == ETIME);
+
+ ACE_Time_Value wait_diff = ACE_OS::gettimeofday () - begin;
+
+ msecs_waited = wait_diff.msec ();
+ msecs_expected = wait_secs * 1000;
+ msecs_diff = labs (msecs_expected - msecs_waited);
+
+ if (msecs_diff > ACE_ALLOWED_SLACK)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Timed wait fails length test\n")));
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Value: %d ms, actual %d ms\n"),
+ msecs_expected,
+ msecs_waited));
+ status = -1;
+ }
+
+ ++wait_secs;
+ return status;
+}
+
+// Explain usage and exit.
+static void
+print_usage_and_die (void)
+{
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("usage: %n [-w n_workers] [-n iteration_count]\n")));
+ ACE_OS::exit (1);
+}
+
+static void
+parse_args (int argc, ACE_TCHAR *argv[])
+{
+ ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("w:n:"));
+
+ int c;
+
+ while ((c = get_opt ()) != -1)
+ switch (c)
+ {
+ case 'w':
+ n_workers = ACE_OS::atoi (get_opt.opt_arg ());
+ break;
+ case 'n':
+ n_iterations = ACE_OS::atoi (get_opt.opt_arg ());
+ break;
+ default:
+ print_usage_and_die ();
+ break;
+ }
+}
+
+// Worker tries to acquire the semaphore, hold it for a while, and
+// then releases it.
+
+static void *
+worker (void *)
+{
+ for (int iterations = 1;
+ iterations <= n_iterations;
+ iterations++)
+ {
+ ACE_Time_Value wait (0,
+ iterations * 1000 * 100); // Wait 'iter' msec
+ ACE_Time_Value tv = ACE_OS::gettimeofday () + wait;
+ if (evt.wait (&tv) == -1)
+ {
+ // verify that we have ETIME
+ ACE_ASSERT(ACE_OS::last_error() == ETIME);
+ ++timeouts;
+ ACE_Time_Value diff = ACE_OS::gettimeofday ();
+ diff = diff - tv; // tv should have been reset to time acquired
+ long diff_msec = diff.msec ();
+
+ if (diff_msec > ACE_ALLOWED_SLACK)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Acquire fails time reset test\n")));
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Diff btw now and returned time: %d ms\n"),
+ diff.msec ()));
+ test_result = 1;
+ }
+ // Hold the lock for a while.
+ ACE_OS::sleep (ACE_Time_Value (0,
+ (ACE_OS::rand () % 1000) * 1000));
+ evt.signal ();
+ }
+
+ ACE_Thread::yield ();
+ }
+
+ return 0;
+}
+
+#endif /* ACE_HAS_THREADS */
+
+// Test event functionality.
+
+int run_main (int argc, ACE_TCHAR *argv[])
+{
+ ACE_START_TEST (ACE_TEXT ("Auto_Event_Test"));
+
+#if defined (ACE_HAS_THREADS)
+ parse_args (argc, argv);
+ ACE_OS::srand (ACE_OS::time (0L));
+
+ //Test timed waits.
+ for (size_t i = 0; i < test_timeout_count; i++)
+ if (test_timeout () != 0)
+ test_result = 1;
+
+ if (ACE_Thread_Manager::instance ()->spawn_n
+ (static_cast<size_t> (n_workers),
+ ACE_THR_FUNC (worker),
+ 0,
+ THR_NEW_LWP) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("spawn_n")),
+ 1);
+
+ // Release the first worker.
+ evt.signal ();
+
+ ACE_Thread_Manager::instance ()->wait ();
+
+ size_t percent = (timeouts * 100) / (n_workers * n_iterations);
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Worker threads timed out %d percent of the time\n"),
+ percent));
+
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Auto_Event Test successful\n")));
+#else
+ ACE_UNUSED_ARG (argc);
+ ACE_UNUSED_ARG (argv);
+ ACE_ERROR ((LM_INFO,
+ ACE_TEXT ("Threads not supported on this platform\n")));
+#endif /* ACE_HAS_THREADS */
+ ACE_END_TEST;
+ return test_result;
+}
diff --git a/tests/Manual_Event_Test.cpp b/tests/Manual_Event_Test.cpp
new file mode 100644
index 00000000000..1b28d846a71
--- /dev/null
+++ b/tests/Manual_Event_Test.cpp
@@ -0,0 +1,205 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// tests
+//
+// = FILENAME
+// Manual_Event Test
+//
+// = DESCRIPTION
+// This test verifies the functionality of the <ACE_Manual_Event>
+// implementation.
+//
+// = AUTHOR
+// Martin Corino <mcorino@remedy.nl>
+//
+// ============================================================================
+
+#include "test_config.h"
+#include "ace/Manual_Event.h"
+#include "ace/Thread.h"
+#include "ace/Thread_Manager.h"
+#include "ace/Get_Opt.h"
+#include "ace/OS_NS_sys_time.h"
+#include "ace/OS_NS_time.h"
+#include "ace/OS_NS_unistd.h"
+#include "ace/Atomic_Op.h"
+
+ACE_RCSID(tests, Manual_Event_Test, "$Id$")
+
+// msec that times are allowed to differ before test fails.
+#if defined (ACE_HAS_HI_RES_TIMER) || defined (ACE_HAS_AIX_HI_RES_TIMER) || \
+ defined (ACE_HAS_PENTIUM) || defined (ACE_HAS_ALPHA_TIMER) || \
+ defined (ACE_HAS_POWERPC_TIMER)
+# define ACE_ALLOWED_SLACK 100
+#else /* don't have a high-res timer */
+# define ACE_ALLOWED_SLACK 1100
+#endif /* don't have a high-res timer */
+
+// Test results, 'success' is 0
+static int test_result = 0;
+
+#if defined (ACE_HAS_THREADS)
+
+// Event used in the tests. Start it "unsignalled" (i.e., its initial
+// state is 0).
+static ACE_Manual_Event evt ((unsigned int) 0);
+
+// Default number of iterations.
+static int n_iterations = 10;
+
+// Number of worker threads.
+static long n_workers = 10;
+
+// Number of wakeups.
+#if defined (ACE_HAS_BUILTIN_ATOMIC_OP)
+static ACE_Atomic_Op<ACE_Thread_Mutex, long> n_awoken;
+static ACE_Atomic_Op<ACE_Thread_Mutex, long> n_awoken2;
+#else
+static long n_awoken;
+static long n_awoken2;
+#endif
+
+// Explain usage and exit.
+static void
+print_usage_and_die (void)
+{
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("usage: %n [-w n_workers] [-n iteration_count]\n")));
+ ACE_OS::exit (1);
+}
+
+static void
+parse_args (int argc, ACE_TCHAR *argv[])
+{
+ ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("w:n:"));
+
+ int c;
+
+ while ((c = get_opt ()) != -1)
+ switch (c)
+ {
+ case 'w':
+ n_workers = ACE_OS::atoi (get_opt.opt_arg ());
+ break;
+ case 'n':
+ n_iterations = ACE_OS::atoi (get_opt.opt_arg ());
+ break;
+ default:
+ print_usage_and_die ();
+ break;
+ }
+}
+
+// Worker tries to acquire the semaphore, hold it for a while, and
+// then manually releases it.
+
+static void *
+worker (void *)
+{
+ if (evt.wait() == -1)
+ {
+ ACE_DEBUG ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) Failed waiting for pulse()\n")));
+ return 0;
+ }
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) awake\n")));
+
+ if (++n_awoken < n_workers)
+ {
+ ACE_Time_Value wait (1, 0); // Wait 10 sec
+ ACE_Time_Value tv = ACE_OS::gettimeofday () + wait;
+
+ if (evt.wait (&tv) == -1)
+ {
+ // verify that we have ETIME
+ ACE_ASSERT(ACE_OS::last_error() == ETIME);
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) timeout\n")));
+ }
+ else
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) awake in time\n")));
+
+ if (++n_awoken2 >= (n_workers/2))
+ evt.reset(); // reset signal (rest times out)
+ }
+ }
+ else
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) last awake; send signal\n")));
+ // last one wakes others
+ evt.signal();
+
+ ACE_OS::sleep (ACE_Time_Value(0, 200 * 1000 * 100)); // 200 msec
+ }
+
+ if (evt.wait() == -1)
+ {
+ ACE_DEBUG ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) Failed waiting for signal()\n")));
+ }
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) worker finished\n")));
+
+ return 0;
+}
+
+#endif /* ACE_HAS_THREADS */
+
+// Test event functionality.
+
+int run_main (int argc, ACE_TCHAR *argv[])
+{
+ ACE_START_TEST (ACE_TEXT ("Manual_Event_Test"));
+
+#if defined (ACE_HAS_THREADS)
+ parse_args (argc, argv);
+
+ if (ACE_Thread_Manager::instance ()->spawn_n
+ (static_cast<size_t> (n_workers),
+ ACE_THR_FUNC (worker),
+ 0,
+ THR_NEW_LWP) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("spawn_n")),
+ 1);
+
+ // gives all workers chance to start
+ ACE_OS::sleep (5);
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("sending pulse()\n")));
+
+ // Release the all workers.
+ evt.pulse ();
+
+ // Wait 2 sec
+ ACE_OS::sleep (2);
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("sending signal()\n")));
+
+ // Signal
+ evt.signal();
+
+ ACE_Thread_Manager::instance ()->wait ();
+
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Manual_Event Test successful\n")));
+#else
+ ACE_UNUSED_ARG (argc);
+ ACE_UNUSED_ARG (argv);
+ ACE_ERROR ((LM_INFO,
+ ACE_TEXT ("Threads not supported on this platform\n")));
+#endif /* ACE_HAS_THREADS */
+ ACE_END_TEST;
+ return test_result;
+}
diff --git a/tests/Process_Manual_Event_Test.cpp b/tests/Process_Manual_Event_Test.cpp
new file mode 100644
index 00000000000..a4bf69ea288
--- /dev/null
+++ b/tests/Process_Manual_Event_Test.cpp
@@ -0,0 +1,209 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// tests
+//
+// = FILENAME
+// Process_Manual_Event_Test.cpp
+//
+// = DESCRIPTION
+// This test verifies the functionality of the <ACE_Manual_Event>
+// processshared implementation.
+//
+// = AUTHOR
+// Martin Corino <mcorino@remedy.nl>
+//
+// ============================================================================
+
+#include "test_config.h"
+#include "ace/Process.h"
+#include "ace/Manual_Event.h"
+#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"
+
+#if !defined (ACE_LACKS_FORK)
+static int iterations = 10;
+static int child_process = 0;
+static const char *event_ping_name = "ACE_Ping_Event";
+static const char *event_pong_name = "ACE_Pong_Event";
+
+// 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)
+{
+ ACE_Manual_Event event_ping (0, USYNC_PROCESS, ACE_TEXT_CHAR_TO_TCHAR (event_ping_name));
+ ACE_Manual_Event event_pong (0, USYNC_PROCESS, ACE_TEXT_CHAR_TO_TCHAR (event_pong_name));
+
+ // Make sure the constructor succeeded
+ ACE_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)
+ {
+ event_ping.signal ();
+
+ if (event_pong.wait ())
+ ACE_DEBUG ((LM_ERROR,
+ ACE_TEXT ("(%P) Failed acquiring pong (%p)\n")));
+ else
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P) Pong\n")));
+ event_pong.reset ();
+ }
+ }
+
+ 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 (event_pong.wait (&wait))
+ ACE_ASSERT(errno == ETIME);
+ else
+ ACE_DEBUG ((LM_ERROR,
+ ACE_TEXT ("(%P) Acquired pong without release()\n")));
+
+ event_ping.signal (); // release waiting parent before timeout
+ }
+ else
+ {
+ for (int i=0; i<iterations ;++i)
+ {
+ if (event_ping.wait ())
+ ACE_DEBUG ((LM_ERROR,
+ ACE_TEXT ("(%P) Failed acquiring ping (%p)\n")));
+ else
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P) Ping\n")));
+ event_ping.reset ();
+ }
+
+ event_pong.signal ();
+ }
+
+ 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 (event_ping.wait (&wait))
+ {
+ ACE_ASSERT(errno == ETIME);
+ ACE_DEBUG ((LM_ERROR,
+ ACE_TEXT ("(%P) Acquiring pong timed out\n")));
+ }
+ }
+}
+#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_Manual_Event_Test"));
+ ACE_ERROR ((LM_INFO,
+ ACE_TEXT ("fork is not supported on this platform\n")));
+ ACE_END_TEST;
+#else /* ! ACE_LACKS_FORK */
+
+ parse_args (argc, argv);
+
+ // Child process code.
+ if (child_process)
+ {
+ ACE_START_TEST (ACE_TEXT ("Process_Manual_Event_Test-child"));
+ acquire_release ();
+ ACE_END_LOG;
+ }
+ else
+ {
+ ACE_START_TEST (ACE_TEXT ("Process_Manual_Event_Test"));
+
+ ACE_Process_Options options;
+ options.command_line (ACE_TEXT (".") ACE_DIRECTORY_SEPARATOR_STR
+ ACE_TEXT ("Process_Manual_Event_Test")
+ ACE_PLATFORM_EXE_SUFFIX
+ ACE_TEXT (" -c -i %d"),
+ iterations);
+
+ // Spawn a child process that will contend for the
+ // lock.
+ ACE_Process child;
+
+ // Spawn the child process.
+ int result = child.spawn (options);
+ ACE_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_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;
+}
diff --git a/tests/Process_Semaphore_Test.cpp b/tests/Process_Semaphore_Test.cpp
new file mode 100644
index 00000000000..16add44af3c
--- /dev/null
+++ b/tests/Process_Semaphore_Test.cpp
@@ -0,0 +1,219 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// tests
+//
+// = FILENAME
+// Process_Semaphore_Test.cpp
+//
+// = DESCRIPTION
+// 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_HAS_POSIX_SEM_TIMEOUT) || defined (ACE_USES_FIFO_SEM) || defined (ACE_HAS_WTHREADS)
+# include "ace/Time_Value.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"
+
+ACE_RCSID(tests, Process_Semaphore_Test, "Process_Semaphore_Test.cpp,v 4.42 2003/12/26 21:59:35 shuston Exp")
+
+#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_HAS_POSIX_SEM_TIMEOUT) || defined (ACE_USES_FIFO_SEM) || defined (ACE_HAS_WTHREADS)
+ 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_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_HAS_POSIX_SEM_TIMEOUT) || defined (ACE_USES_FIFO_SEM) || defined (ACE_HAS_WTHREADS)
+ 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_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_HAS_POSIX_SEM_TIMEOUT) || defined (ACE_USES_FIFO_SEM) || defined (ACE_HAS_WTHREADS)
+ 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_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 /* ! ACE_LACKS_FORK */
+
+ 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_Process_Options options;
+ options.command_line (ACE_TEXT (".") ACE_DIRECTORY_SEPARATOR_STR
+ ACE_TEXT ("Process_Semaphore_Test")
+ ACE_PLATFORM_EXE_SUFFIX
+ ACE_TEXT (" -c -i %d"),
+ iterations);
+
+ // Spawn a child process that will contend for the
+ // lock.
+ ACE_Process child;
+
+ // Spawn the child process.
+ int result = child.spawn (options);
+ ACE_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_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;
+}
diff --git a/tests/Semaphore_Test.cpp b/tests/Semaphore_Test.cpp
index 7232666ff10..e2b82042559 100644
--- a/tests/Semaphore_Test.cpp
+++ b/tests/Semaphore_Test.cpp
@@ -55,7 +55,7 @@ static size_t n_workers = 10;
// Amount to release the semaphore.
static u_int n_release_count = 3;
-#if !defined (ACE_HAS_STHREADS) && !defined (ACE_HAS_POSIX_SEM)
+#if !defined (ACE_HAS_STHREADS) && (!defined (ACE_HAS_POSIX_SEM) || defined (ACE_HAS_POSIX_SEM_TIMEOUT))
// Number of timeouts.
static size_t timeouts = 0;
@@ -151,7 +151,7 @@ worker (void *)
iterations <= n_iterations;
iterations++)
{
-#if !defined (ACE_HAS_STHREADS) && !defined (ACE_HAS_POSIX_SEM)
+#if !defined (ACE_HAS_STHREADS) && (!defined (ACE_HAS_POSIX_SEM) || defined (ACE_HAS_POSIX_SEM_TIMEOUT))
ACE_Time_Value wait (0,
iterations * 1000 * 100); // Wait 'iter' msec
ACE_Time_Value tv = ACE_OS::gettimeofday () + wait;
@@ -203,7 +203,7 @@ int run_main (int argc, ACE_TCHAR *argv[])
parse_args (argc, argv);
ACE_OS::srand (ACE_OS::time (0L));
-# if !defined (ACE_HAS_STHREADS) && !defined (ACE_HAS_POSIX_SEM)
+# if !defined (ACE_HAS_STHREADS) && (!defined (ACE_HAS_POSIX_SEM) || defined (ACE_HAS_POSIX_SEM_TIMEOUT))
//Test timed waits.
for (size_t i = 0; i < test_timeout_count; i++)
if (test_timeout () != 0)
@@ -225,7 +225,7 @@ int run_main (int argc, ACE_TCHAR *argv[])
ACE_Thread_Manager::instance ()->wait ();
-# if !defined (ACE_HAS_STHREADS) && !defined (ACE_HAS_POSIX_SEM)
+# if !defined (ACE_HAS_STHREADS) && (!defined (ACE_HAS_POSIX_SEM) || defined (ACE_HAS_POSIX_SEM_TIMEOUT))
size_t percent = (timeouts * 100) / (n_workers * n_iterations);
ACE_DEBUG ((LM_DEBUG,
diff --git a/tests/run_test.lst b/tests/run_test.lst
index 0562f3b9f1c..b79d885edcd 100644
--- a/tests/run_test.lst
+++ b/tests/run_test.lst
@@ -20,6 +20,7 @@ ACE_Test
Arg_Shifter_Test
Array_Map_Test
Atomic_Op_Test
+Auto_Event_Test
Auto_IncDec_Test
Barrier_Test
Basic_Types_Test
@@ -96,7 +97,9 @@ Proactor_Scatter_Gather_Test: !chorus !VxWorks !LynxOS
Proactor_Test: !chorus !VxWorks !LynxOS
Proactor_Timer_Test: !chorus !VxWorks !LynxOS
Process_Manager_Test: !chorus !VxWorks
+Process_Manual_Event_Test: !chorus !VxWorks !LynxOS
Process_Mutex_Test: !chorus !VxWorks !LynxOS
+Process_Semaphore_Test: !chorus !VxWorks !LynxOS
RB_Tree_Test
Reactor_Dispatch_Order_Test
Reactor_Exceptions_Test
diff --git a/tests/tests.mpc b/tests/tests.mpc
index ce499beb7cc..1a5ac07da83 100644
--- a/tests/tests.mpc
+++ b/tests/tests.mpc
@@ -112,6 +112,13 @@ project(Atomic Op Test) : acetest {
}
}
+project(Auto Event Test) : acetest {
+ exename = Auto_Event_Test
+ Source_Files {
+ Auto_Event_Test.cpp
+ }
+}
+
project(Auto IncDec Test) : acetest {
exename = Auto_IncDec_Test
Source_Files {
@@ -376,6 +383,13 @@ project(Malloc Test) : acetest {
}
}
+project(Manual_Event Test) : acetest {
+ exename = Manual_Event_Test
+ Source_Files {
+ Manual_Event_Test.cpp
+ }
+}
+
project(Map Test) : acetest {
exename = Map_Test
Source_Files {
@@ -551,6 +565,13 @@ project(Proactor Timer Test) : acetest {
}
}
+project(Process Manual Event Test) : acetest {
+ exename = Process_Manual_Event_Test
+ Source_Files {
+ Process_Manual_Event_Test.cpp
+ }
+}
+
project(Process Mutex Test) : acetest {
exename = Process_Mutex_Test
Source_Files {
@@ -558,6 +579,13 @@ project(Process Mutex Test) : acetest {
}
}
+project(Process Semaphore Test) : acetest {
+ exename = Process_Semaphore_Test
+ Source_Files {
+ Process_Semaphore_Test.cpp
+ }
+}
+
project(Process Strategy Test) : acetest {
exename = Process_Strategy_Test
Source_Files {