예제 #1
0
파일: main.cpp 프로젝트: CCJY/ACE
int
ACE_TMAIN (int, ACE_TCHAR *argv[])
{
  ACE_Service_Config daemon;
  ACE_ARGV new_args;

  // Load the existing <argv> into our new one.
  new_args.add (argv);
  // Enable loading of static services.
  new_args.add (ACE_TEXT ("-y"));
  // Enable debugging within dynamically linked services.
  new_args.add (ACE_TEXT ("-d"));

  ACE_DEBUG ((LM_DEBUG,
              ACE_TEXT ("argc = %d\n"),
              new_args.argc ()));

  // Print the contents of the combined <ACE_ARGV>.
  for (int i = 0; i < new_args.argc (); i++)
    ACE_DEBUG ((LM_DEBUG,
                ACE_TEXT ("(%d) %s\n"),
                i,
                new_args.argv ()[i]));

  if (daemon.open (new_args.argc (),
                   new_args.argv ()) == -1)
    {
      if (errno != ENOENT)
        ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("open")),
                          1);
      else // Use static binding.
        {
          ACE_ARGV args;

          args.add (argv[0]);
          args.add (ACE_TEXT ("-p10011")); // Port number.
          ACE_Service_Object *so =
            ACE_SVC_INVOKE (ACE_Naming_Context);

          if (so->init (args.argc (),
                        args.argv ()) == -1)
            ACE_ERROR_RETURN ((LM_ERROR,
                               ACE_TEXT ("%p\n"),
                               ACE_TEXT ("ACE_Naming_Context")),
                              1);
        }
    }

  Client_Test test_body;
  if (test_body.open () == -1)
    return 1;

  // Run forever, performing the configured services until we are shut
  // down by a SIGINT/SIGQUIT signal.

  ACE_Reactor::instance ()->run_reactor_event_loop ();
  test_body.close ();

  return 0;
}
예제 #2
0
int
main (int argc, char *argv[])
{
  ACE_Service_Config loggerd;
  Event_Handler handler;
  ACE_Sig_Adapter shutdown_handler ((ACE_Sig_Handler_Ex) ACE_Reactor::end_event_loop);

  if (ACE_Event_Handler::register_stdin_handler (&handler,
						 ACE_Reactor::instance (),
						 ACE_Thread_Manager::instance ()) == -1)
    ACE_ERROR ((LM_ERROR,
                "%p\n",
                "register_stdin_handler"));

  if (loggerd.open (argc,
                    argv,
                    ACE_DEFAULT_LOGGER_KEY,
                    // Don't ignore static services!
                    0) == -1 && errno != ENOENT)
    ACE_ERROR ((LM_ERROR,
                "%p\n%a",
                "open",
                1));
  else if (ACE_Reactor::instance ()->register_handler
    (SIGINT, &shutdown_handler) == -1)
    ACE_ERROR ((LM_ERROR,
                "%p\n%a",
                "register_handler",
                1));

  // Perform logging service until we receive SIGINT.

  ACE_Reactor::run_event_loop ();
  return 0;
}
예제 #3
0
파일: server.cpp 프로젝트: asdlei00/ACE
int
ACE_TMAIN(int, ACE_TCHAR **)
{
  int result = 0;
#if 0
  ACE_Service_Config serviceConfig;

  char signum[64];
  ACE_OS::sprintf(signum, "%d", SIGUSR1);

  ACE_ARGV args;
  args.add(argv[0]);
  args.add("-s");
  args.add(signum);

  result = serviceConfig.open (
    args.argc(),
    args.argv(),
    ACE_DEFAULT_LOGGER_KEY,
    1, // ignore_static_svcs = 1,
    1, // ignore_default_svc_conf_file = 0,
    0  // ignore_debug_flag = 0
  );
  if(0 != result)
  {
    ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) Error: serviceConfig.open failed\n")));
    return result;
  }
  ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%P|%t) serviceConfig.open done\n")));
#endif

  for(int cnt = 0; cnt < 1000; ++cnt)
  {
    ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%P|%t) Loading ORB cnt = %d\n"), cnt));
    result = ACE_Service_Config::process_directive(scpc_loadOrb);
    if(0 != result)
    {
      ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) Error loading ORB failed (%d)\n"), result));
      return result;
    }
    ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%P|%t) Loading ORB done\n")));

    result = ACE_Service_Config::process_directive(scpc_unloadOrb);
    if(0 != result)
    {
      ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) Error unloading ORB failed (%d)\n"), result));
      return result;
    }
    ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%P|%t) Unloading ORB done\n")));
  }

  return result;
}
예제 #4
0
int
ACE_TMAIN (int argc, ACE_TCHAR *argv[])
{
  ACE_Service_Config daemon;

  daemon.open (argv[0]);

  // Register a signal handler.
  ACE_Sig_Action sa ((ACE_SignalHandler) handler, SIGINT);
  ACE_UNUSED_ARG (sa);

  int n_threads = argc > 1 ? ACE_OS::atoi (argv[1]) : DEFAULT_THREADS;
  intptr_t n_iterations =
    argc > 2 ? ACE_OS::atoi (argv[2]) : DEFAULT_ITERATIONS;

  ACE_Thread_Manager *thr_mgr = ACE_Thread_Manager::instance ();

  int grp_id = thr_mgr->spawn_n (n_threads,
                                 ACE_THR_FUNC (worker),
                                 reinterpret_cast<void *> (n_iterations),
                                 THR_NEW_LWP | THR_DETACHED);

  // Wait for 1 second and then suspend every thread in the group.
  ACE_OS::sleep (1);
  ACE_DEBUG ((LM_DEBUG, "(%t) suspending group\n"));
  if (thr_mgr->suspend_grp (grp_id) == -1)
    ACE_ERROR ((LM_DEBUG, "(%t) %p\n", "suspend_grp"));

  // Wait for 1 more second and then resume every thread in the
  // group.
  ACE_OS::sleep (ACE_Time_Value (1));
  ACE_DEBUG ((LM_DEBUG, "(%t) resuming group\n"));
  if (thr_mgr->resume_grp (grp_id) == -1)
    ACE_ERROR ((LM_DEBUG, "(%t) %p\n", "resume_grp"));

  // Wait for 1 more second and then send a SIGINT to every thread in
  // the group.
  ACE_OS::sleep (ACE_Time_Value (1));
  ACE_DEBUG ((LM_DEBUG, "(%t) signaling group\n"));
  if (thr_mgr->kill_grp (grp_id, SIGINT) == -1)
    ACE_ERROR ((LM_DEBUG, "(%t) %p\n", "kill_grp"));

  // Wait for 1 more second and then cancel all the threads.
  ACE_OS::sleep (ACE_Time_Value (1));
  ACE_DEBUG ((LM_DEBUG, "(%t) cancelling group\n"));
  if (thr_mgr->cancel_grp (grp_id) == -1)
    ACE_ERROR ((LM_DEBUG, "(%t) %p\n", "cancel_grp"));

  // Perform a barrier wait until all the threads have shut down.
  thr_mgr->wait ();
  return 0;
}
예제 #5
0
파일: combined.cpp 프로젝트: CCJY/ATCD
int ACE_TMAIN (int argc, ACE_TCHAR *argv[])
{
  try {

    ACE_Service_Config config;
    config.open (argc, argv);

    ORB_var orb = ORB_init (argc, argv);

    Object_var obj = orb->resolve_initial_references("RootPOA");
    POA_var poa = POA::_narrow(obj.in());
    ACE_ASSERT(! is_nil(poa.in()));
    POAManager_var poaman = poa->the_POAManager();

    SvcConf svt(config);

    ObjectId_var id = poa->activate_object(&svt);
    obj = poa->id_to_reference(id.in());
    ACE_ASSERT(! is_nil(obj.in()));
    String_var ior = orb->object_to_string(obj.in());

    poaman->activate();

    {
      ofstream out("combined.ior");
      out << ior;
    }

    ACE_DEBUG((LM_DEBUG, "Combined service started.\n"));

    orb->run();

    ACE_DEBUG((LM_DEBUG, "Combined service shutdown.\n"));

    poa->destroy(1, 1);
    orb->destroy();

  } catch (const CORBA::Exception& e) {
    e._tao_print_exception ("Combined Service:");
  }
  return 0;
}
예제 #6
0
파일: main.cpp 프로젝트: binghuo365/BaseLab
int
ACE_TMAIN (int argc, ACE_TCHAR *argv[])
{
  ACE_Service_Config daemon;

  ACE_OS::signal (SIGCHLD, SIG_IGN);

  // SigAction not needed since the handler will shutdown the server.
  ACE_OS::signal (SIGINT, (ACE_SignalHandler) handler);
  ACE_OS::signal (SIGUSR2, (ACE_SignalHandler) handler);

  if (daemon.open (argc, argv, ACE_DEFAULT_LOGGER_KEY, 0) != 0)
    ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), 1);

  // The configured service creates threads, and the
  // server won't exit until the threads die.

  // Run forever, performing the configured services until we receive
  // a SIGINT.


  return 0;
}
예제 #7
0
int
ACE_TMAIN (int argc, ACE_TCHAR *argv[])
{
    ACE_Service_Config daemon;

    daemon.open (argv[0]);

    int n_threads = argc > 1 ? ACE_OS::atoi (argv[1]) : DEFAULT_THREADS;
    intptr_t n_iterations =
        argc > 2 ? ACE_OS::atoi (argv[2]) : DEFAULT_ITERATIONS;

    ACE_Thread_Manager *thr_mgr = ACE_Thread_Manager::instance ();

    int grp_id = thr_mgr->spawn_n (n_threads, ACE_THR_FUNC (worker),
                                   (void *) n_iterations,
                                   THR_NEW_LWP | THR_DETACHED);

    // Wait for 2 seconds and then suspend every thread in the group.
    ACE_OS::sleep (2);
    thr_mgr->suspend_grp (grp_id);

    // Wait for 2 more seconds and then resume every thread in the
    // group.
    ACE_OS::sleep (ACE_Time_Value (2));
    thr_mgr->resume_grp (grp_id);

    // Wait for 2 more seconds and then send a SIGINT to every thread in
    // the group.
    ACE_OS::sleep (ACE_Time_Value (2));
    thr_mgr->kill_grp (grp_id, SIGINT);

    // Wait for 2 more seconds and then exit (which should kill all the
    // threads)!
    ACE_OS::sleep (ACE_Time_Value (2));

    return 0;
}
예제 #8
0
void
testLoadingServiceConfFile (int argc, ACE_TCHAR *argv[])
{
  ACE_ARGV new_argv;

#if defined (ACE_USES_WCHAR)
  // When using full Unicode support, use the version of the Service
  // Configurator file appropriate to the platform.
  // For example, Windows Unicode uses UTF-16.
  //
  //          iconv(1) found on Linux and Solaris, for example, can
  //          be used to convert between encodings.
  //
  //          Byte ordering is also an issue, so we should be
  //          generating this file on-the-fly from the UTF-8 encoded
  //          file by using functions like iconv(1) or iconv(3).
#  if defined (ACE_WIN32)
  const ACE_TCHAR svc_conf[] =
    ACE_TEXT ("Service_Config_Test.UTF-16")
    ACE_TEXT (ACE_DEFAULT_SVC_CONF_EXT);
#  else
  const ACE_TCHAR svc_conf[] =
    ACE_TEXT ("Service_Config_Test.WCHAR_T")
    ACE_TEXT (ACE_DEFAULT_SVC_CONF_EXT);
#  endif /* ACE_WIN32 */
#else
    // ASCII (UTF-8) encoded Service Configurator file.
  const ACE_TCHAR svc_conf[] =
    ACE_TEXT ("Service_Config_Test")
    ACE_TEXT (ACE_DEFAULT_SVC_CONF_EXT);
#endif  /* ACE_USES_WCHAR */

  // Process the Service Configurator directives in this test's
  if (new_argv.add (argv) == -1
              || new_argv.add (ACE_TEXT ("-f")) == -1
              || new_argv.add (svc_conf) == -1)
    {
      ACE_ERROR ((LM_ERROR,
                  ACE_TEXT ("line %l %p\n"),
                  ACE_TEXT ("new_argv.add")));
      ++error;
    }

  // We need this scope to make sure that the destructor for the
  // <ACE_Service_Config> gets called.
  ACE_Service_Config daemon;

  if (daemon.open (new_argv.argc (), new_argv.argv ()) == -1)
    {
      if (errno == ENOENT)
        ACE_DEBUG ((LM_WARNING,
                    ACE_TEXT ("ACE_Service_Config::open: %p\n"),
                    svc_conf));
      else
        ACE_ERROR ((LM_ERROR,
                    ACE_TEXT ("ACE_Service_Config::open: %p\n"),
                    ACE_TEXT ("error")));
    }

  ACE_Time_Value tv (argc > 1 ? ACE_OS::atoi (argv[1]) : 2);

  if (ACE_Reactor::instance()->run_reactor_event_loop (tv) == -1)
    {
      ++error;
      ACE_ERROR ((LM_ERROR,
                  ACE_TEXT ("line %l %p\n"),
                  ACE_TEXT ("run_reactor_event_loop")));
    }

  // Wait for all threads to complete.
  ACE_Thread_Manager::instance ()->wait ();
}
예제 #9
0
void
testLoadingServiceConfFileAndProcessNo (int argc, ACE_TCHAR *argv[])
{
  u_int error0 = error;
  ACE_ARGV new_argv;

  ACE_DEBUG ((LM_DEBUG, ACE_TEXT("Starting testLoadingServiceConfFileAndProcessNo\n")));

#if defined (ACE_USES_WCHAR)
  // When using full Unicode support, use the version of the Service
  // Configurator file appropriate to the platform.
  // For example, Windows Unicode uses UTF-16.
  //
  //          iconv(1) found on Linux and Solaris, for example, can
  //          be used to convert between encodings.
  //
  //          Byte ordering is also an issue, so we should be
  //          generating this file on-the-fly from the UTF-8 encoded
  //          file by using functions like iconv(1) or iconv(3).
#  if defined (ACE_WIN32)
  const ACE_TCHAR svc_conf[] =
    ACE_TEXT ("Service_Config_Test.UTF-16")
    ACE_TEXT (ACE_DEFAULT_SVC_CONF_EXT);
#  else
  const ACE_TCHAR svc_conf[] =
    ACE_TEXT ("Service_Config_Test.WCHAR_T")
    ACE_TEXT (ACE_DEFAULT_SVC_CONF_EXT);
#  endif /* ACE_WIN32 */
#else
    // ASCII (UTF-8) encoded Service Configurator file.
  const ACE_TCHAR svc_conf[] =
    ACE_TEXT ("Service_Config_Test")
    ACE_TEXT (ACE_DEFAULT_SVC_CONF_EXT);
#endif  /* ACE_USES_WCHAR */

  ACE_TCHAR pid_file_name [MAXPATHLEN];
#if defined (TEST_DIR)
  ACE_OS::strcpy (pid_file_name, TEST_DIR);
  ACE_OS::strcat (pid_file_name, ACE_DIRECTORY_SEPARATOR_STR);
  ACE_OS::strcat (pid_file_name, ACE_TEXT ("Service_Config_Test.pid"));
#else
  ACE_OS::strcpy (pid_file_name, ACE_TEXT ("Service_Config_Test.pid"));
#endif
  ACE_TCHAR svc_conf_file_name [MAXPATHLEN];
#if defined (TEST_DIR)
  ACE_OS::strcpy (svc_conf_file_name, TEST_DIR);
  ACE_OS::strcat (svc_conf_file_name, ACE_DIRECTORY_SEPARATOR_STR);
  ACE_OS::strcat (svc_conf_file_name, svc_conf);
#else
  ACE_OS::strcpy (svc_conf_file_name, svc_conf);
#endif

  // Process the Service Configurator directives in this test's Making
  // sure we have more than one option with an argument, to capture
  // any errors caused by "reshuffling" of the options.
  if (new_argv.add (argv) == -1
              || new_argv.add (ACE_TEXT ("-d")) == -1
              || new_argv.add (ACE_TEXT ("-k")) == -1
              || new_argv.add (ACE_TEXT ("xxx")) == -1
              || new_argv.add (ACE_TEXT ("-p")) == -1
              || new_argv.add (pid_file_name) == -1
              || new_argv.add (ACE_TEXT ("-f")) == -1
              || new_argv.add (svc_conf_file_name) == -1)
    {
      ACE_ERROR ((LM_ERROR,
                  ACE_TEXT ("line %l %p\n"),
                  ACE_TEXT ("new_argv.add")));
      ++error;
    }

  // We need this scope to make sure that the destructor for the
  // <ACE_Service_Config> gets called.
  ACE_Service_Config daemon;

  ACE_DEBUG ((LM_DEBUG, ACE_TEXT("Starting daemon using %s\n"), new_argv.buf ()));

  if (daemon.open (new_argv.argc (), new_argv.argv ()) == -1 &&
      errno != ENOENT)
    {
      ACE_ERROR ((LM_ERROR,
                  ACE_TEXT ("line %l %p\n"),
                  ACE_TEXT ("daemon.open")));
      ++error;
    }

  ACE_Time_Value tv (argc > 1 ? ACE_OS::atoi (argv[1]) : 2);

  if (ACE_Reactor::instance()->run_reactor_event_loop (tv) == -1)
    {
      ++error;
      ACE_ERROR ((LM_ERROR,
                  ACE_TEXT ("line %l %p\n"),
                  ACE_TEXT ("run_reactor_event_loop")));
    }

  // Wait for all threads to complete.
  ACE_Thread_Manager::instance ()->wait ();

  if (error == error0)
    ACE_DEBUG ((LM_DEBUG, ACE_TEXT("testLoadingServiceConfFileAndProcessNo completed successfully\n")));
  else
    ACE_ERROR ((LM_ERROR, ACE_TEXT("testLoadingServiceConfFileAndProcessNo test failed\n")));
}
예제 #10
0
파일: server.cpp 프로젝트: asdlei00/ACE
int
ACE_TMAIN(int, ACE_TCHAR ** argv)
{
  int result = 0;
#if !defined (ACE_LACKS_FORK)
  ACE_Sig_Action sigUSR2((ACE_SignalHandler) shutdown_func, SIGUSR2);
  ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%P|%t) SIGUSR2 shutdown handler installed\n")));
  ACE_UNUSED_ARG(sigUSR2);

  pid_t pid = -1;
  pid = ACE_OS::fork();
  ACE_Log_Msg::instance ()->sync (argv[0]); // Make %P|%t work right

  if (pid == 0) // child
  {
    ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%P|%t) child waiting\n")));
    ACE_OS::sleep(5);
    ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%P|%t) signaling parent\n")));
    result = ACE_OS::kill(ACE_OS::getppid(), SIGUSR2);
    ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%P|%t) signaled parent\n")));
    //    ACE_OS::sleep (100000);
    return 0;
  }
  else if (pid > 0) // parent
  {
    ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%P|%t) parent using ACE_Service_Config, pid=%d\n"), pid));
    ACE_Service_Config serviceConfig;

    ACE_TCHAR signum[64];
    ACE_OS::sprintf(signum, ACE_TEXT("%d"), SIGUSR1);

    ACE_ARGV args;
    args.add(argv[0]);
    args.add(ACE_TEXT("-s"));
    args.add(signum);

    result = serviceConfig.open (
      args.argc(),
      args.argv(),
      ACE_DEFAULT_LOGGER_KEY,
      1, // ignore_static_svcs = 1,
      1, // ignore_default_svc_conf_file = 0,
      0  // ignore_debug_flag = 0
    );
    if(0 != result)
    {
      ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) Error: serviceConfig.open failed\n")));
      return result;
    }
    ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%P|%t) serviceConfig.open done\n")));

    ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%P|%t) serviceConfig.process_file ...\n")));
#if (ACE_USES_CLASSIC_SVC_CONF == 1)
    result = serviceConfig.process_file(ACE_TEXT("Bug_3251.conf"));
#else
    result = serviceConfig.process_file(ACE_TEXT("Bug_3251.conf.xml"));
#endif
    if(0 != result)
    {
      ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) Error: serviceConfig.process_file failed\n")));
      return result;
    }
    ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%P|%t) serviceConfig.process_file done\n")));

    ACE_DEBUG ((LM_INFO, ACE_TEXT ("run_event_loop ...\n")));
    while(!bShutdown)
    {
      ACE_OS::last_error(0);
      result = ACE_Reactor::run_event_loop();
      // reenter loop on EINTR
      if(0 != result && EINTR == ACE_OS::last_error())
      {
        if(bShutdown)
          break;
      }
      else if(0 != result)
      {
        ACE_DEBUG ((
          LM_INFO,
          ACE_TEXT ("(%P|%t) run_event_loop failed (%s, %d)\n"),
          ACE_OS::strerror(ACE_OS::last_error()),
          ACE_OS::last_error()
        ));
      }
    }

    ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%P|%t) run_event_loop done\n")));

    ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%P|%t) serviceConfig.fini_svcs ...\n")));
    result = serviceConfig.fini_svcs();
    if(0 != result)
    {
      ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) Error: serviceConfig.fini_svcs failed\n")));
      return result;
    }
    ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%P|%t) serviceConfig.fini_svcs done\n")));

    ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%P|%t) serviceConfig.close ...\n")));
    result = serviceConfig.close();
    if(0 != result)
    {
      ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) Error: serviceConfig.close failed\n")));
      return result;
    }
    ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%P|%t) serviceConfig.close done\n")));

    return result;
  } /* end of if */
  else // fork failed
  {
    ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) Error: fork failed\n")));
    return 1;
  } /* end of else */
#else
  ACE_UNUSED_ARG (argv);
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Fork not available\n")));
#endif
  return result;
}
예제 #11
0
int
ACE_TMAIN (int argc, ACE_TCHAR *argv[])
{
  ACE_Service_Config daemon;

  daemon.open (argv[0]);

  parse_args (argc, argv);

  if (child)
    {
      worker (n_iterations);

      ACE_OS::exit (exit_code);
    }

  ACE_DEBUG ((LM_DEBUG,
              "(%P|%t@%T) Process_Manager test.  Expect output from"
              "2 or 3 processes...\n"));

  ACE_Process_Manager::instance ()->register_handler
    (new ExitHandler ("default"));

  pid_t pid1 = respawn_self (argv[0],
                             n_iterations,
                             111);
  pid_t pid2 = respawn_self (argv[0],
                             n_iterations + 500,
                             222);

#if !defined (ACE_WIN32)
  pid_t pid3 = ACE_OS::fork ();

  if (!pid3)
    {
      worker (n_iterations);
      return 999;
    }
#endif /* ACE_WIN32 */

  ACE_Process_Manager::instance ()->register_handler (new ExitHandler ("specific"),
                                                      pid2);

  if (pid1 == ACE_INVALID_PID || pid2 == ACE_INVALID_PID)
    ACE_ERROR_RETURN ((LM_ERROR,
                       "(%P|%t) %p\n",
                       "start_n"),
                      1);

  ACE_DEBUG ((LM_DEBUG,
              "(%P|%t@%T) Test parent waiting (synchronously, "
              "up to 6 seconds) for children...\n"));

  int result =
    ACE_Process_Manager::instance ()->wait (ACE_Time_Value (6));

  ACE_DEBUG ((LM_DEBUG,
              "(%P|%t@%T) Test parent: %d processes left\n",
              result));

  if (result > 0)
    {
      ACE_DEBUG ((LM_DEBUG,
                  "(%P|%t@%T) Test parent waiting (synchronously, "
                  "indefinitely) for remaining children...\n"));
      result =
        ACE_Process_Manager::instance ()->wait ();
      ACE_DEBUG ((LM_DEBUG,
                  "(%P|%t@%T) Test parent finished waiting: %d\n",
                  result));
    }

  ACE_DEBUG ((LM_DEBUG,
              "(%P|%t@%T) Test parent: try auto-reap functions\n"));

  ACE_Process_Manager::instance ()->open (ACE_Process_Manager::DEFAULT_SIZE,
                                          ACE_Reactor::instance ());

  pid1 = respawn_self (argv[0],
                       n_iterations + 200,
                       333 );
  pid2 = respawn_self (argv[0],
                       n_iterations + 500,
                       444);

#if !defined (ACE_WIN32)
  pid3 = ACE_OS::fork ();

  if (!pid3)
    {
      worker (n_iterations);
      return 888;
    }
#endif /* ACE_WIN32 */

  ExitHandler *main_thread_work = 0;
  ACE_NEW_RETURN (main_thread_work,
                  ExitHandler ("main thread worker"),
                  1);

  ACE_Reactor::instance ()->schedule_timer (main_thread_work,
                                            0,
                                            ACE_Time_Value (2),
                                            ACE_Time_Value (1, 500000));
  ACE_DEBUG ((LM_DEBUG,
              "(%P|%t@%T) Test parent: expect several Processes "
              "to be auto-detected over the next 30 seconds.\n"
              "The main thread will do some other work, too.\n" ));

  ACE_Time_Value briefly (30);

  result = ACE_Reactor::run_event_loop (briefly);

  ACE_DEBUG ((LM_DEBUG,
              "(%P|%t@%T) Test parent: finished (%d) %d.%d.  Close"
              "Process_Manager...\n",
              result,
              briefly.sec (),
              briefly.usec ()));

  ACE_Process_Manager::instance ()->close ();

  return 0;
}