static int
parent (char *shm)
{
  // This for loop executes in a critical section proteced by
  // <parent_mutex>.
  for (int i = 0; i < SHMSZ; i++)
    shm[i] = SHMDATA[i];

  int result;
  result = parent_mutex->release ();
  ACE_ASSERT (result != -1);

  result = parent_synch->acquire ();
  ACE_ASSERT (result != -1);

  result = myallocator ().remove ();
  ACE_ASSERT (result != -1);

  result = parent_mutex->remove ();
  ACE_ASSERT (result != -1);

  result = parent_synch->remove ();
  ACE_ASSERT (result != -1);

  return 0;
}
Beispiel #2
0
static int
parent (Test_Data *data)
{
  MALLOC *myalloc = myallocator ();

  {
    ACE_GUARD_RETURN (ACE_Process_Mutex, guard, myalloc->mutex (), -1);
    print ("parent", data);
  }

  // Sleep for a 200 msecs so that the child will have a chance to spin!
  ACE_OS::sleep (ACE_Time_Value (0, 200 * 1000));

#if defined (ACE_TEST_REMAP_ON_FAULT)
  char *small_buf[1024];
  int cntr;

  for (cntr = 0 ; cntr < 1024; ++cntr)
    small_buf[cntr] = (char *) myalloc->malloc (1);
  char *big_buf = (char *) myalloc->malloc (1024 * 4069);
#endif /* ACE_TEST_REMAP_ON_FAULT */

  int result = myalloc->bind ("bar", data);

#if defined (ACE_TEST_REMAP_ON_FAULT)
  myalloc->free (big_buf);
  for (cntr = 0 ; cntr < 1024; ++cntr)
    myalloc->free (small_buf[cntr]);
#endif /* ACE_TEST_REMAP_ON_FAULT */

  ACE_TEST_ASSERT (result != -1);
  return 0;
}
Beispiel #3
0
static int
child (void)
{
  void *bar = 0;
  // Perform "busy waiting" here until the parent stores data under a
  // new name called "bar" in <ACE_Malloc>.  This isn't a good design
  // -- it's just to test that synchronization is working across
  // processes via <ACE_Malloc>.
  for (ACE_Time_Value timeout (0, 1000 * 10);
       myallocator ()->find ("bar",
                             bar) == -1;
       )
    {
      ACE_DEBUG ((LM_DEBUG,
                  ACE_TEXT ("(%P) sleeping for 10 milliseconds!\n")));
      ACE_OS::sleep (timeout);
    }

  print ("child",
         reinterpret_cast<Test_Data *> (bar));
  return 0;
}
Beispiel #4
0
int
run_main (int argc, ACE_TCHAR *argv[])
{
#if defined (ACE_WIN32)
  get_base_addrs();
#endif

  if (argc == 1)
    {
      ACE_START_TEST (ACE_TEXT ("Malloc_Test"));
      ACE_INIT_LOG (ACE_TEXT ("Malloc_Test-child"));

      init_test (PARENT_BASE_ADDR);

      ACE_Control_Block::print_alignment_info ();
# if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
      ACE_PI_Control_Block::print_alignment_info ();
# endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1 */

      // No arguments means we're the parent process.
      ACE_Process_Options options (1);

#if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
      static const ACE_TCHAR* format = ACE_TEXT ("%ls%ls%ls");
#else
      static const ACE_TCHAR* format = ACE_TEXT ("%s%s%s");
#endif /* !ACE_WIN32 && ACE_USES_WCHAR */
      options.command_line (format, EXE_LOCATION,
                            argc > 0 ? argv[0] : ACE_TEXT ("Malloc_Test"),
                            ACE_TEXT (" run_as_test"));

      MALLOC *myalloc = myallocator (PARENT_BASE_ADDR);

      Test_Data *data = initialize (myalloc);
      ACE_TEST_ASSERT (data != 0);

      ACE_DEBUG ((LM_DEBUG,
                  ACE_TEXT ("(%P) PARENT allocator at = %@, ")
                  ACE_TEXT ("data allocated at %@\n"),
                  myalloc,
                  data));
      myalloc->dump ();
      int result = myalloc->bind ("foo", data);
      ACE_TEST_ASSERT (result != -1);

      ACE_Process p;
      pid_t pid = p.spawn (options);
      if (pid == -1)
        ACE_ERROR_RETURN ((LM_ERROR,
                           ACE_TEXT ("%p\n"),
                           ACE_TEXT ("spawn")), 1);

      parent (data);

      // Synchronize on the exit of the child.
      result = p.wait ();
      if (result == -1)
        ACE_ERROR_RETURN ((LM_ERROR,
                           ACE_TEXT ("%p\n"),
                           ACE_TEXT ("wait")), 1);
      ACE_TEST_ASSERT (myalloc->ref_counter () == 1);
      myalloc->remove ();
      ACE_END_TEST;
      return 0;
    }
  else
    {
      // In this case we're the child process.
      ACE_APPEND_LOG (ACE_TEXT ("Malloc_Test-child"));

      void *data = 0;
      MALLOC *myalloc = myallocator (CHILD_BASE_ADDR);
      int result = myalloc->find ("foo", data);
      ACE_TEST_ASSERT (result != -1);

      ACE_DEBUG ((LM_DEBUG,
                  ACE_TEXT ("(%P) CHILD allocator at = %@, ")
                  ACE_TEXT ("data allocated at %@\n"),
                  myalloc,
                  data));
      myalloc->dump ();
      child ();
      myalloc->release ();
      ACE_END_LOG;
      return 0;
    }
}
// $Id: SV_Shared_Memory_Test.cpp 79346 2007-08-14 23:29:36Z sowayaa $

// ============================================================================
//
// = LIBRARY
//    tests
//
// = FILENAME
//    SV_Shared_Memory_Test.cpp
//
// = DESCRIPTION
//     This is a simple test of <ACE_SV_Shared_Memory> and
//     <ACE_Malloc> using the <ACE_Shared_Memory_Pool>.  The test
//     forks two processes and then executes client and server
//     allowing them to exchange data using shared memory. No user
//     input is required as far as command line arguments are
//     concerned.
//
// = AUTHOR
//    Prashant Jain <*****@*****.**>
//    and Douglas C. Schmidt <*****@*****.**>
//
// ============================================================================

#include "test_config.h"
#include "ace/Malloc_T.h"
#include "ace/Shared_Memory_Pool.h"
#include "ace/SV_Semaphore_Simple.h"
#include "ace/SV_Semaphore_Complex.h"
#include "ace/OS_NS_unistd.h"


ACE_RCSID(tests, SV_Shared_Memory_Test, "$Id: SV_Shared_Memory_Test.cpp 79346 2007-08-14 23:29:36Z sowayaa $")

#if defined (ACE_HAS_SYSV_IPC) && !defined(ACE_LACKS_SYSV_SHMEM)

// The shared memory allocator, which uses up the ACE_DEFAULT_SEM_KEY.
// We hide the allocator inside this function so that it doesn't get
// constructed until after the ACE_Object_Manager gets constructed,
// even with ACE_HAS_NONSTATIC_OBJECT_MANAGER.

static
ACE_Malloc<ACE_SHARED_MEMORY_POOL, ACE_SV_Semaphore_Simple> &
myallocator (void)
{
  static ACE_Malloc<ACE_SHARED_MEMORY_POOL,
                    ACE_SV_Semaphore_Simple> myallocator;
  return myallocator;
}

// Create some more keys that are different from the
// ACE_DEFAULT_SEM_KEY used by the allocator.
static const int SEM_KEY_1 = ACE_DEFAULT_SEM_KEY + 1;
static const int SEM_KEY_2 = ACE_DEFAULT_SEM_KEY + 2;

static const int SHMSZ = 27;
static const char SHMDATA[SHMSZ] = "abcdefghijklmnopqrstuvwxyz";

static ACE_SV_Semaphore_Complex *parent_mutex = 0;
static ACE_SV_Semaphore_Complex *parent_synch = 0;

static int
parent (char *shm)
{
  // This for loop executes in a critical section proteced by
  // <parent_mutex>.
  for (int i = 0; i < SHMSZ; i++)
    shm[i] = SHMDATA[i];

  int result;
  result = parent_mutex->release ();
  ACE_ASSERT (result != -1);

  result = parent_synch->acquire ();
  ACE_ASSERT (result != -1);

  result = myallocator ().remove ();
  ACE_ASSERT (result != -1);

  result = parent_mutex->remove ();
  ACE_ASSERT (result != -1);

  result = parent_synch->remove ();
  ACE_ASSERT (result != -1);

  return 0;
}

static int
child (char *shm)
{
  int result;

  ACE_SV_Semaphore_Complex mutex;

  // This semaphore is initially created with a count of 0, i.e., it
  // is "locked."
  result = mutex.open (SEM_KEY_1,
                       ACE_SV_Semaphore_Complex::ACE_CREATE,
                       0);
  ACE_ASSERT (result != -1);

  ACE_SV_Semaphore_Complex synch;
  // This semaphore is initially created with a count of 0, i.e., it
  // is "locked."
  result = synch.open (SEM_KEY_2,
                       ACE_SV_Semaphore_Complex::ACE_CREATE,
                       0);
  ACE_ASSERT (result != -1);

  // Perform "busy waiting" here until we acquire the semaphore.  This
  // isn't really a good design -- it's just to illustrate that you
  // can do non-blocking acquire() calls with the ACE System V
  // semaphore wrappers.
  while ((result = mutex.tryacquire ()) == -1)
    if (errno == EAGAIN)
      ACE_DEBUG ((LM_DEBUG,
                  ACE_TEXT ("(%P) spinning in child!\n")));
    else
      {
        ACE_ERROR ((LM_ERROR,
                    ACE_TEXT ("(%P) child mutex.tryacquire")));
        ACE_ASSERT (result != -1);
      }

  for (int i = 0; i < SHMSZ; i++)
    ACE_ASSERT (SHMDATA[i] == shm[i]);

  result = synch.release ();
  ACE_ASSERT (result != -1);

  return 0;
}

#endif /* ACE_HAS_SYSV_IPC */
int
run_main (int, ACE_TCHAR *[])
{
  ACE_START_TEST (ACE_TEXT ("SV_Shared_Memory_Test"));

#if defined (ACE_HAS_SYSV_IPC) && !defined (ACE_LACKS_FORK) && \
    !defined(ACE_LACKS_SYSV_SHMEM)

  // Check whether allocator was initialized.
  if (myallocator ().bad ())
    {
      ACE_ERROR_RETURN ((LM_ERROR,
                         ACE_TEXT ("Unable to initialize allocator\n")),
                         -1);
    }

  char *shm = reinterpret_cast<char *> (myallocator ().malloc (SHMSZ));

  // Create the mutex and synch before spawning the child process, to
  // avoid race condition between their creation in the parent and use
  // in the child.
  ACE_NEW_RETURN (parent_mutex,
                  ACE_SV_Semaphore_Complex,
                  -1);
  ACE_NEW_RETURN (parent_synch,
                  ACE_SV_Semaphore_Complex,
                  -1);

  // This semaphore is initially created with a count of 0, i.e., it
  // is "locked."
  int result = parent_mutex->open (SEM_KEY_1,
                                   ACE_SV_Semaphore_Complex::ACE_CREATE,
                                   0);
  ACE_ASSERT (result != -1);

  // This semaphore is initially created with a count of 0, i.e., it
  // is "locked."
  result = parent_synch->open (SEM_KEY_2,
                               ACE_SV_Semaphore_Complex::ACE_CREATE,
                               0);
  ACE_ASSERT (result != -1);

  switch (ACE_OS::fork (ACE_TEXT ("SV_Shared_Memory_Test.cpp")))
    {
    case -1:
      ACE_ERROR_RETURN ((LM_ERROR,
                         ACE_TEXT ("(%P) fork failed\n")),
                        -1);
      /* NOTREACHED */
    case 0:
      child (shm);
      break;
    default:
      parent (shm);
      delete parent_mutex;
      delete parent_synch;
      break;
    }
#else
  ACE_ERROR ((LM_INFO,
              ACE_TEXT ("SYSV IPC, SYSV SHMEM, or fork ")
              ACE_TEXT ("are not supported on this platform\n")));
#endif /* ACE_HAS_SYSV_IPC */
  ACE_END_TEST;
  return 0;
}