launcher_rvgl::~launcher_rvgl() { if (_rvgl_pid != ACE_INVALID_PID) { ACE_DEBUG((LM_INFO, "launcher_rvgl::dtor removing pid %d\n", _rvgl_pid)); ACE_Process_Manager *pm = ACE_Process_Manager::instance(); pm->remove(_rvgl_pid); } }
int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) { if (argc > 1) // Running as a child. { ACE_OS::sleep (10); } else // Running as a parent. { // Get the processwide process manager. ACE_Process_Manager* pm = ACE_Process_Manager::instance (); // Specify the options for the new processes // to be spawned. ACE_Process_Options options; options.command_line (ACE_TEXT ("%s a"), argv[0]); // Spawn two child processes. pid_t pids[NCHILDREN]; pm->spawn_n (NCHILDREN, options, pids); // Destroy the first child. pm->terminate (pids[0]); // Wait for the child we just terminated. ACE_exitcode status; pm->wait (pids[0], &status); // Get the results of the termination. #if !defined(ACE_WIN32) if (WIFSIGNALED (status) != 0) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d died because of a signal ") ACE_TEXT ("of type %d\n"), pids[0], WTERMSIG (status))); #else ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("The process terminated with exit code %d\n"), status)); #endif /*ACE_WIN32*/ // Wait for all (only one left) of the // children to exit. pm->wait (0); } return 0; }
int launcher_rvgl::_launch(const std::string &host_id) { if (_running) return err_already_running; std::string dir = pref()->get<std::string>("advanced/rvgl_path", ""); std::string params = pref()->get<std::string>("advanced/rvgl_cmdline", ""); if (dir.empty()) { win_registry r(win_registry::id_dplay, "", "Re-Volt"); dir = r.get<std::string>("Path", ""); pref()->set("advanced/rvgl_path", dir.c_str()); } std::string cmd(dir); #ifdef WIN32 cmd += "/rvgl.exe"; #else cmd += "/rvgl"; #endif cmd = "\"" + cmd + "\""; if (!params.empty()) cmd += " " + params; cmd += (host_id.empty() ? " -lobby" : " -lobby " + host_id); //printf("%s\n", cmd.c_str()); ACE_DEBUG((LM_DEBUG, "launcher_rvgl: command line: %s\n", cmd.c_str())); // Launch options ACE_Process_Manager *pm = ACE_Process_Manager::instance(); ACE_Process_Options opts; opts.working_directory(dir.c_str()); opts.command_line(cmd.c_str()); _rvgl_pid = pm->spawn(opts, this); ACE_DEBUG((LM_INFO, "launcher_rvgl: pid %d from thread %t, cmd: %s\n", _rvgl_pid, cmd.c_str())); if (_rvgl_pid == ACE_INVALID_PID) { ACE_ERROR((LM_ERROR, "launcher_rvgl: failed to launch: %s\n", cmd.c_str())); return err_could_not_launch; } _running = true; return 0; }
bool Service_Manager::run_proxyd() { ACE_ARGV proxyd_args; proxyd_args.add(this->args.argv()[0]); proxyd_args.add("rungamed"); ACE_Process_Manager* pmgr = ACE_Process_Manager::instance(); ACE_Process_Options pop; pop.command_line(proxyd_args.argv()); pid_t proxyd_pid = pmgr->spawn(pop); if (proxyd_pid == ACE_INVALID_PID) return false; ServiceInfo* si = new ServiceInfo(proxyd_pid); this->svcs.insert(std::pair<MorpheusServices, ServiceInfo*>(GAMESERVER, si)); ACE_DEBUG((LM_DEBUG,"Proxyd runs at pid %u\n", proxyd_pid)); return true; }
bool Service_Manager::run_realmd() { ACE_ARGV realmd_args; realmd_args.add(this->args.argv()[0]); realmd_args.add("runrealmd"); ACE_Process_Manager* pmgr = ACE_Process_Manager::instance(); ACE_Process_Options pop; pop.command_line(realmd_args.argv()); pid_t realmpid = pmgr->spawn(pop); if (realmpid == ACE_INVALID_PID) return false; ServiceInfo *si = new ServiceInfo(realmpid); this->svcs.insert(std::pair<MorpheusServices, ServiceInfo*>(LOGINSERVER, si)); ACE_DEBUG((LM_DEBUG,"Realmd runs at pid %u\n", realmpid)); return true; }
int Service_Monitor::svc(void) { ACE_OS::printf("(%u) Service_Monitor starting up...\n", ACE_OS::thr_self()); int use_svm_ini = 0; // Get_Opt ACE_Get_Opt cmd(this->argc_, this->argv_); cmd.long_option(ACE_TEXT("svm"), ACE_Get_Opt::NO_ARG); cmd.long_option(ACE_TEXT("svc"), ACE_Get_Opt::NO_ARG); int ch; while( (ch = cmd()) != EOF ) { switch(ch) { case 0: if ( ACE_OS::strcasecmp(cmd.last_option(), "svm") == 0 ) use_svm_ini = 1; break; } } // load monitors ( use_svm_ini )?this->load("svm.ini"):this->import_svc_ini("svc.ini"); Service_Control sc(0, 0); sc.load("svc.ini"); ACE_Process_Manager* pm = ACE_Process_Manager::instance(); size_t n_count = 0; while( !stop_.value() ) { { ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, this->lock_, -1); for(MONITORS::iterator it = monitors_.begin(); it != monitors_.end(); ++it) { if ( it->second > 0 && n_count % it->second == 0 ) { const char* service = it->first.c_str(); int rc = 0; //+ get pid first. if connected, don't call start() int plock = sc.plock(service); // pid_t p_id = sc.pid(service); if ( !plock ) // if ( p_id < 0 ) { std::string cmd("."); cmd += ACE_DIRECTORY_SEPARATOR_CHAR; cmd += "svc "; cmd += service; cmd += " start"; /* //?? better to wake up service by system() ACE_OS::system(cmd.c_str()); //*/ ACE_Process_Options opt; opt.command_line(cmd.c_str()); #ifdef ACE_WIN32 opt.creation_flags(CREATE_NO_WINDOW); #endif ///* pid_t start_pid = pm->spawn(opt); if ( start_pid != ACE_INVALID_PID ) pm->wait(start_pid); //*/ // log: service is starting again char buf[256]; int n_buf = ACE_OS::snprintf(buf, 255, "[%s] is starting again!\n", service); SVM_LOG->log(buf, n_buf); //ACE_OS::printf("%s", buf); //@ /* Service_Control::SERVICES::const_iterator iter = sc.find(service); if ( iter != sc.end() ) { rc = sc.start(service, iter->second.c_str()); const char* time_to_wait = 0; pid_t start_pid = sc.wait_for_start(service, time_to_wait); // log: service is starting again //+ log restart event here!! char buf[256]; int n_buf = ACE_OS::snprintf(buf, 255, "[%s] is starting again!\n", service); SVM_LOG->log(buf, n_buf); //SVM_LOGGER()->log(buf, n_buf, &ACE_OS::gettimeofday()); } else { rc = -1; //+ log: service is not found // don't log?? ACE_OS::printf("%d\t[%s]\tservice command is not found!\n", rc, service); //@ } //*/ } else { //+ log: service is already running // don't log?? ACE_OS::printf("+%d\t[%s]\tservice is still running!\n", rc, service); //@ } } } } ++n_count; ACE_Time_Value sleep_tv; sleep_tv.set(0.1); for(int i=0; i<10; ++i) { if ( stop_.value() ) break; ACE_OS::sleep(sleep_tv); } } //pm->wait(); ACE_OS::printf("(%u) Service_Monitor shutting down...\n", ACE_OS::thr_self()); return 0; }
static pid_t spawn_child (const ACE_TCHAR *argv0, ACE_Process_Manager &mgr, int sleep_time, int my_process_id) { #if defined (ACE_HAS_WINCE) const ACE_TCHAR *cmdline_format = ACE_TEXT("%s %d"); #elif defined (ACE_WIN32) const ACE_TCHAR *cmdline_format = ACE_TEXT("\"%s\" %s %d"); #elif !defined (ACE_USES_WCHAR) const ACE_TCHAR *cmdline_format = ACE_TEXT (".") ACE_DIRECTORY_SEPARATOR_STR ACE_TEXT("%s %s %d"); #else const ACE_TCHAR *cmdline_format = ACE_TEXT (".") ACE_DIRECTORY_SEPARATOR_STR ACE_TEXT("%ls %ls %d"); #endif ACE_Process_Options opts; ACE_TCHAR prio[64]; ACE_TCHAR cmd[16]; if (debug_test) ACE_OS::strcpy (cmd, ACE_TEXT ("-d")); else cmd[0] = ACE_TEXT ('\0'); #if defined (ACE_HAS_WIN32_PRIORITY_CLASS) if (my_process_id == 1) { opts.creation_flags (ABOVE_NORMAL_PRIORITY_CLASS); ACE_OS::snprintf (prio, 64, ACE_TEXT ("and priority 'above normal'")); } else if (my_process_id == 2) { opts.creation_flags (BELOW_NORMAL_PRIORITY_CLASS); ACE_OS::snprintf (prio, 64, ACE_TEXT ("and priority 'below normal'")); } else if (my_process_id == 3) { opts.creation_flags (IDLE_PRIORITY_CLASS); ACE_OS::snprintf (prio, 64, ACE_TEXT ("and priority 'idle'")); } else if (my_process_id == 4) { opts.creation_flags (HIGH_PRIORITY_CLASS); ACE_OS::snprintf (prio, 64, ACE_TEXT ("and priority 'high'")); } else if (my_process_id == 5) { opts.creation_flags (NORMAL_PRIORITY_CLASS); ACE_OS::snprintf (prio, 64, ACE_TEXT ("and priority 'normal'")); } else prio[0] = ACE_TEXT ('\0'); ACE_TCHAR pd [16]; ACE_OS::snprintf (pd, 16, ACE_TEXT (" -p %d"), my_process_id); ACE_OS::strcat (cmd, pd); #else ACE_UNUSED_ARG (my_process_id); prio[0] = ACE_TEXT ('\0'); #endif opts.process_name (argv0); #ifndef ACE_LACKS_VA_FUNCTIONS opts.command_line (cmdline_format, #if !defined (ACE_HAS_WINCE) argv0, #endif /* !ACE_HAS_WINCE */ cmd, sleep_time); #else ACE_UNUSED_ARG (cmdline_format); #endif /* ACE_LACKS_VA_FUNCTIONS */ ACE_DEBUG ((LM_DEBUG, ACE_TEXT("Spawning <%s> <%s>\n"), opts.process_name(), opts.command_line_buf ())); pid_t result = mgr.spawn (opts); if (result != ACE_INVALID_PID) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P) spawned child: pid %d time %d %s\n"), int (result), sleep_time, prio)); else ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("spawn failed"))); return result; }
int run_main (int argc, ACE_TCHAR *argv[]) { #if defined (ACE_HAS_WIN32_PRIORITY_CLASS) ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("dp:")); #else ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("d")); #endif int opt; while ((opt = get_opt ()) != EOF) { switch (opt) { case 'd': debug_test = 1u; break; #if defined (ACE_HAS_WIN32_PRIORITY_CLASS) case 'p': process_id = ACE_OS::atoi (get_opt.opt_arg ()); break; #endif } } if (get_opt.opt_ind () == argc - 1) { // child process: sleep & exit ACE_TCHAR lognm[MAXPATHLEN]; int const mypid (ACE_OS::getpid ()); ACE_OS::snprintf (lognm, MAXPATHLEN, ACE_TEXT ("Process_Manager_Test-child-%d"), mypid); ACE_START_TEST (lognm); int const secs = ACE_OS::atoi (argv[get_opt.opt_ind ()]); ACE_OS::sleep (secs ? secs : 1); ACE_TCHAR prio[64]; #if defined (ACE_WIN32_HAS_PRIORITY_CLASS) DWORD priority = ::GetPriorityClass (::GetCurrentProcess()); check_process_priority(priority); if (priority == ABOVE_NORMAL_PRIORITY_CLASS) ACE_OS::snprintf (prio, 64, ACE_TEXT ("and priority 'above normal'")); else if (priority == BELOW_NORMAL_PRIORITY_CLASS) ACE_OS::snprintf (prio, 64, ACE_TEXT ("and priority 'below normal'")); else if (priority == HIGH_PRIORITY_CLASS) ACE_OS::snprintf (prio, 64, ACE_TEXT ("and priority 'high'")); else if (priority == IDLE_PRIORITY_CLASS) ACE_OS::snprintf (prio, 64, ACE_TEXT ("and priority 'idle'")); else if (priority == NORMAL_PRIORITY_CLASS) ACE_OS::snprintf (prio, 64, ACE_TEXT ("and priority 'normal'")); else if (priority == REALTIME_PRIORITY_CLASS) ACE_OS::snprintf (prio, 64, ACE_TEXT ("and priority 'realtime'")); #else prio[0] = ACE_TEXT ('\0'); #endif if (debug_test) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%T: pid %P about to exit with code %d %s\n"), secs, prio)); ACE_END_LOG; return secs; } if (get_opt.opt_ind () != argc) // incorrect usage usage (argv[0]); ACE_START_TEST (ACE_TEXT ("Process_Manager_Test")); int test_status = 0; #ifdef ACE_HAS_PROCESS_SPAWN int result = 0; if ((result = command_line_test ()) != 0) test_status = result; // Try the explicit <ACE_Process_Manager::wait> functions ACE_Process_Manager mgr; mgr.register_handler (new Exit_Handler ("default")); ACE_exitcode exitcode; // -------------------------------------------------- // wait for a specific PID pid_t child1 = spawn_child (argc > 0 ? argv[0] : ACE_TEXT ("Process_Manager_Test"), mgr, 1, 1); result = mgr.wait (child1, &exitcode); if (result != child1) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P) Error: expected to reap child1 (%d); got %d\n"), child1, result)); if (result == ACE_INVALID_PID) ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P) %p\n"), ACE_TEXT ("error"))); test_status = 1; } else ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P) reaped child1, pid %d: %d\n"), child1, exitcode)); // -------------------------------------------------- // wait for a specific PID; another should finish first pid_t child2 = spawn_child (argc > 0 ? argv[0] : ACE_TEXT ("Process_Manager_Test"), mgr, 1, 2); pid_t child3 = spawn_child (argc > 0 ? argv[0] : ACE_TEXT ("Process_Manager_Test"), mgr, 4, 3); result = mgr.wait (child3, &exitcode); if (result != child3) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P) Error: expected to reap child3 (%d); got %d\n"), child3, result)); if (result == ACE_INVALID_PID) ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P) %p\n"), ACE_TEXT ("error"))); test_status = 1; } else ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P) reaped child 3, pid %d: %d\n"), child3, exitcode)); // Now wait for any...should get the one that finished earlier. result = mgr.wait (0, &exitcode); if (result != child2) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P) Error: expected to reap child2 (%d); got %d\n"), child2, result)); if (result == ACE_INVALID_PID) ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P) %p\n"), ACE_TEXT ("error"))); test_status = 1; } else ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P) reaped child 2, pid %d: %d\n"), result, exitcode)); // -------------------------------------------------- // Try the timed wait functions // This one shouldn't timeout: pid_t child4 = spawn_child (argc > 0 ? argv[0] : ACE_TEXT ("Process_Manager_Test"), mgr, 1, 4); #if defined (ACE_HAS_CPP11) result = mgr.wait (0, std::chrono::seconds (4), &exitcode); #else result = mgr.wait (0, ACE_Time_Value (4), &exitcode); #endif if (result != child4) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P) Error: expected to reap child4 (%d); got %d\n"), child4, result)); if (result == ACE_INVALID_PID) ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P) %p\n"), ACE_TEXT ("error"))); test_status = 1; } else ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P) reaped child 4 pid %d: %d\n"), result, exitcode)); // This one should timeout: pid_t child5 = spawn_child (argc > 0 ? argv[0] : ACE_TEXT ("Process_Manager_Test"), mgr, 4, 5); result = mgr.wait (0, ACE_Time_Value (1), &exitcode); if (result != 0) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P) Error: expected wait to time out; got %d\n"), result)); if (result == ACE_INVALID_PID) ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P) %p\n"), ACE_TEXT ("error"))); test_status = 1; } else ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P) Correctly timed out wait at child 5\n"))); // Now wait indefinitely to clean up... result = mgr.wait (0, &exitcode); if (result != child5) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("Error: expected to reap child5 pid %d; got %d\n"), child5, result)); if (result == ACE_INVALID_PID) ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P) %p\n"), ACE_TEXT ("error"))); test_status = 1; } else ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P) reaped child 5, pid %d: %d\n"), result, exitcode)); // Terminate a child process and make sure we can wait for it. pid_t child6 = spawn_child (argc > 0 ? argv[0] : ACE_TEXT ("Process_Manager_Test"), mgr, 5, 6); ACE_exitcode status6; if (-1 == mgr.terminate (child6)) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P) %p\n"), ACE_TEXT ("terminate child6"))); test_status = 1; mgr.wait (child6, &status6); // Wait for child to exit just to clean up } else { if (-1 == mgr.wait (child6, &status6)) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P) wait on child6 reported ACE_INVALID_PID\n"))); test_status = 1; } else { // Get the results of the termination. #if !defined(ACE_WIN32) if (WIFSIGNALED (status6) != 0) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P) child6 died on signal %d - correct\n"), WTERMSIG (status6))); else ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P) child6 should have died on signal, ") ACE_TEXT ("but didn't; exit status %d\n"), WEXITSTATUS (status6))); #else ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P) The process terminated with exit code %d\n"), status6)); #endif /*ACE_WIN32*/ } } #ifdef ACE_HAS_THREADS Process_Task task1 (argc > 0 ? argv[0] : ACE_TEXT ("Process_Manager_Test"), mgr, 3); Process_Task task2 (argc > 0 ? argv[0] : ACE_TEXT ("Process_Manager_Test"), mgr, 2); Process_Task task3 (argc > 0 ? argv[0] : ACE_TEXT ("Process_Manager_Test"), mgr, 1); task1.open (0); task2.open (0); task3.open (0); while (running_tasks!=0) { ACE_OS::sleep (1); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P) still running tasks\n"))); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P) result: '%C'\n"), order.c_str ())); if (order != "321123") { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P) wrong order of spawns ('%C', should be '321123')\n"), order.c_str ())); test_status = 1; } #endif /* ACE_HAS_THREADS */ #if !defined (ACE_OPENVMS) && \ (defined ACE_WIN32 || !defined ACE_LACKS_UNIX_SIGNALS) // -------------------------------------------------- // Finally, try the reactor stuff... mgr.open (ACE_Process_Manager::DEFAULT_SIZE, ACE_Reactor::instance ()); pid_t child7 = spawn_child (argc > 0 ? argv[0] : ACE_TEXT ("Process_Manager_Test"), mgr, 5, 7); /* pid_t child8 = */ spawn_child (argc > 0 ? argv[0] : ACE_TEXT ("Process_Manager_Test"), mgr, 6, 0); mgr.register_handler (new Exit_Handler ("specific"), child7); ACE_Time_Value how_long (10); ACE_Reactor::instance ()->run_reactor_event_loop (how_long); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P) Reactor loop done!\n") )); size_t const nr_procs = mgr.managed (); if (nr_procs != 0) ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P) %d processes left in manager\n"), nr_procs)); #endif /* !defined (ACE_OPENVMS) */ #endif // ACE_HAS_PROCESS_SPAWN ACE_END_TEST; return test_status; }