/* * This function simply stops the service p. * @param s A Service_T object * @return TRUE if the service was stopped otherwise FALSE */ static int do_stop(Service_T s) { ASSERT(s); if(s->depend_visited) return TRUE; s->depend_visited= TRUE; monitor_unset(s); if(s->type==TYPE_PROCESS) { /* Reset the proc info object in case of a later restart */ memset(s->procinfo, 0, sizeof *(s->procinfo)); } if(s->stop && (s->type!=TYPE_PROCESS || is_process_running(s))) { log("stop: (%s) %s\n", s->name, s->stop->arg[0]); spawn(s, s->stop, "Stopped"); if(s->type==TYPE_PROCESS) { /* Only wait for process service types */ return wait_stop(s); } } return TRUE; }
int main(int argc, char* argv[]) { std::cout << "b.exe argumentrs" << std::endl; for (int i = 0; i < argc; ++i) { std::cout << "i = " << i << " "<< argv[i] << std::endl; } DWORD PID; std::stringstream ss; ss << argv[0]; ss >> PID; std::cout << "b.exe: wait for PID " << PID << std::endl; while (is_process_running(PID)) { std::this_thread::sleep_for(std::chrono::milliseconds(1)); } std::cout << "b.exe: end of wait" << std::endl; boost::filesystem::rename("c.exe", "a.exe"); STARTUPINFO info={sizeof(info)}; PROCESS_INFORMATION processInfo; CreateProcess("a.exe", nullptr, nullptr, nullptr, true, 0, nullptr, nullptr, &info, &processInfo); std::cout << "b.exe: end" << std::endl; }
/* * This function waits for the service to stop running. If the service * did not stop a failed event is posted to notify the user. This * function does purposefully not run in its own thread because, if we * did a restart we need to know if we successfully managed to stop * the service first before we can do a start. * @param service A Service to wait for * @return TRUE if the service was stopped otherwise FALSE */ static int wait_stop(Service_T s) { int max_tries= Run.polltime; ASSERT(s); while(max_tries-- && !Run.stopped) { if(!is_process_running(s)) break; sleep(1); } if(is_process_running(s)) { Event_post(s, EVENT_FAILED, "Failed to stop '%s'\n", s->name); return FALSE; } return TRUE; }
/** Returns true if there is already another Vidalia process running. */ bool is_vidalia_running(const QString &pidfile) { /* Read the pidfile and find out if that process still exists */ qint64 pid = read_pidfile(pidfile); if (pid > 0) { #if defined(Q_OS_WIN32) if (QSysInfo::WindowsVersion == QSysInfo::WV_NT) { /* We currently can't get a list of running processes on Windows NT, so * be pessimistic and assume the existence of a nonzero pidfile means * Vidalia is running. */ return true; } else return (is_process_running(pid)); #else return (is_process_running(pid)); #endif } return false; }
// run_for takes a function and runs it for a certain amount of time // run_for will return within 1 second of your function exiting, if it // exits before the specified time. void run_for(float howLong, void (*funky)) { int pid=start_process(funky); while(howLong >= 1.0){ if(!is_process_running(pid)) return; sleep(1.0); howLong=howLong-1.0; } sleep(howLong); kill_process(pid); return; }
/* * This function runs in it's own thread and waits for the service to * start running. If the service did not start a failed event is * posted to notify the user. * @param service A Service to wait for */ static void *wait_start(void *service) { Service_T s= service; int max_tries= Run.polltime; ASSERT(s); pthread_detach(pthread_self()); while(max_tries-- && !Run.stopped) { if(is_process_running(s)) break; sleep(1); } if(!is_process_running(s)) { Event_post(s, EVENT_FAILED, "Failed to start '%s'\n", s->name); } return NULL; }
/* * This is a post- fix recursive function for starting every service * that s depends on before starting s. * @param s A Service_T object */ static void do_start(Service_T s) { ASSERT(s); if(s->visited) return; s->visited= TRUE; if(s->dependantlist) { Dependant_T d; for(d= s->dependantlist; d; d= d->next ) { Service_T parent= get_service(d->dependant); ASSERT(parent); do_start(parent); } } if(s->start && (s->type!=TYPE_PROCESS || !is_process_running(s))) { int status; pthread_t thread; log("start: (%s) %s\n", s->name, s->start->arg[0]); spawn(s, s->start, "Started"); if(s->type==TYPE_PROCESS) { /* We only wait for a process type, other service types does not * have a pid file to watch */ status= pthread_create(&thread, NULL, wait_start, s); if(status != 0) { log("Warning: Failed to create the start controller thread. " "Thread error -- %s.\n", strerror(status)); } } } monitor_set(s); }
/** * we will store the temporary files in [tmp_directory]/graphlab/[procid] * This searches in graphlab's temp directory for unused temporary files * (what procids no longer exist) and deletes them. */ EXPORT void reap_unused_temp_files() { // loop through all the subdirectories in get_graphlab_temp_directory() // and unlink if the pid does not exist size_t temp_dir_size = num_temp_directories(); for (size_t idx = 0; idx < temp_dir_size; ++idx) { try { fs::path temp_dir(get_graphlab_temp_directory(idx)); auto diriter = fs::directory_iterator(temp_dir); auto enditer = fs::directory_iterator(); while(diriter != enditer) { auto path = diriter->path(); if (fs::is_directory(path)) { try { long pid = std::stol(path.filename().string()); if(!is_process_running(pid)) { // PID no longer exists. // delete it logstream(LOG_EMPH) << "Deleting orphaned temp directory found in " << path.string() << std::endl; delete_proc_directory(path); } } catch (...) { // empty catch. if the path does not parse as an // integer, ignore it. logstream(LOG_WARNING) << "Unexpcted file in GraphLab's temp directory: " << path << std::endl; } } ++diriter; } } catch (...) { // Failures are ok. we just stop. } } }
/** * Validate a given process service s. Events are posted according to * its configuration. In case of a fatal event FALSE is returned. */ int check_process(Service_T s) { pid_t pid= -1; Port_T pp= NULL; Resource_T pr= NULL; char report[STRLEN]={0}; /* Test for running process */ if(!(pid= is_process_running(s))) { /* Reset the proc info object to prevent false data in the first run */ memset(s->procinfo, 0, sizeof *(s->procinfo)); Event_post(s, EVENT_START, "Event: Process '%s' is not running.\n", s->name); return FALSE; } else { DEBUG("'%s' is running with pid %d\n", s->name, (int)pid); } if(Run.doprocess) { if(update_process_data(s, ptree, ptreesize, pid)) { if(! check_process_state(s, report)) { Event_post(s, EVENT_RESOURCE, "Event: %s\n", report); } else { DEBUG("'%s' check_process_state() passed.\n", s->name); } for(pr= s->resourcelist; pr; pr= pr->next) { if(!check_process_resources(s, pr, report)) { pr->cycle=0; if(! pr->event_handled) { pr->event_flag= TRUE; pr->event_handled= TRUE; if(! eval_actions(pr->action, s, report, "resource", EVENT_RESOURCE)) { reset_resource_counter(s); return FALSE; } } } else { pr->event_handled= FALSE; } } } else { log("'%s' failed to get service data\n", s->name); } } /* Test each host:port and protocol in the service's portlist */ for(pp= s->portlist; pp; pp= pp->next) { if(!check_process_connection(s, pp, report)) { if(! pp->event_handled) { pp->event_flag= TRUE; pp->event_handled= TRUE; if(! eval_actions(pp->action, s, report, "connection", EVENT_CONNECTION)) { return FALSE; } } } else { pp->event_handled= FALSE; } } return TRUE; }
/** * Check to see if we should try to start/stop service * @param P A service name as stated in the config file * @param action A string describing the action to execute * @return TRUE if the service was handled successfully otherwise FALSE */ void check_service(const char *P, const char *action) { Service_T s= NULL; ASSERT(P); ASSERT(action); if(NULL==(s= get_service(P))) { log("%s: Cannot %s program '%s' -- not found in %s\n", prog, action, P, Run.controlfile); return; } if(IS(action, "start")) { if(s->type==TYPE_PROCESS && is_process_running(s)) { DEBUG("%s: Process already running -- process %s\n", prog, P); monitor_set(s); return; } if(s->type==TYPE_PROCESS && !s->start) { DEBUG("%s: Start method not defined -- process %s\n", prog, P); monitor_set(s); return; } do_depend(s, "stop"); do_start(s); do_depend(s, "start"); } else if(IS(action, "stop")) { if(s->type==TYPE_PROCESS && !s->stop) { DEBUG("%s: Stop method not defined -- process %s\n", prog, P); monitor_unset(s); return; } do_depend(s, "stop"); do_stop(s); } else if(IS(action, "restart")) { if(s->type==TYPE_PROCESS && (!s->start || !s->stop)) { DEBUG("%s: Start or stop method not defined -- process %s\n", prog, P); monitor_set(s); return; } else { log("Trying to restart '%s'\n", s->name); } do_depend(s, "stop"); if(do_stop(s)) { /* Only start if stop succeeded */ do_start(s); do_depend(s, "start"); } } else if(IS(action, "monitor")) { /* We only enable monitoring of this service and all prerequisite * services. Chain of services which depends on this service keep * its state */ do_monitor(s); } else if(IS(action, "unmonitor")) { /* We disable monitoring of this service and all services which * depends on it */ do_depend(s, "unmonitor"); do_unmonitor(s); } }