예제 #1
0
파일: thread.py 프로젝트: pestctrl/lutris
    def get_processes(self):
        process = Process(self.rootpid)
        num_children = 0
        num_watched_children = 0
        terminated_children = 0
        passed_terminal_procs = False
        processes = defaultdict(list)
        for child in self.iter_children(process):
            # Exclude terminal processes
            if self.terminal:
                if child.name == "run_in_term.sh":
                    passed_terminal_procs = True
                if not passed_terminal_procs:
                    continue

            num_children += 1
            if child.pid in self.old_pids:
                processes['external'].append(str(child))
                continue

            if (child.name and child.name in self.exclude_processes and
               child.name not in self.include_processes):
                processes['excluded'].append(str(child))
                continue
            num_watched_children += 1
            processes['monitored'].append(str(child))
            if child.state == 'Z':
                terminated_children += 1
        for child in self.monitored_processes['monitored']:
            if child not in processes['monitored']:
                num_children += 1
                num_watched_children += 1
        return processes, num_children, num_watched_children, terminated_children
예제 #2
0
def is_running():
    pid = system.get_pid("Steam.exe$")
    if pid:
        # If process is defunct, don't consider it as running
        process = Process(pid)
        return process.state != "Z"
    return False
예제 #3
0
    def refresh_process_status(self):
        """Return status of a process"""
        old_children, self.children = self.children, []
        old_ignored_children, self.ignored_children = self.ignored_children, []

        for child in self.iter_children(Process(os.getpid())):
            if child.state == 'Z':  # should never happen anymore...
                logger.debug("Unexpected zombie process %s", child)
                try:
                    os.wait3(os.WNOHANG)
                except ChildProcessError:
                    pass
                continue

            if (child.name and child.name in self.exclude_processes
                    and child.name not in self.include_processes):
                self.ignored_children.append(child)
            else:
                self.children.append(child)

        self._log_changes('ignored', old_ignored_children,
                          self.ignored_children)
        self._log_changes('monitored', old_children, self.children)

        return len(self.children) > 0
예제 #4
0
파일: wine.py 프로젝트: gorgobacka/lutris
def winekill(prefix,
             arch='win32',
             wine_path=None,
             env=None,
             initial_pids=None):
    """Kill processes in Wine prefix."""

    initial_pids = initial_pids or []
    for pid in initial_pids:
        logger.debug(Process(pid))

    if not wine_path:
        wine_path = wine().get_executable()
    wine_root = os.path.dirname(wine_path)
    if not env:
        env = {'WINEARCH': arch, 'WINEPREFIX': prefix}
    command = [os.path.join(wine_root, "wineserver"), "-k"]

    logger.debug("Killing all wine processes: %s" % command)
    logger.debug("\tWine prefix: %s", prefix)
    logger.debug("\tWine arch: %s", arch)
    logger.debug("\tInitial pids: %s", initial_pids)

    system.execute(command, env=env, quiet=True)

    logger.debug("Waiting for wine processes to terminate")
    # Wineserver needs time to terminate processes
    num_cycles = 0
    while True:
        num_cycles += 1
        running_processes = [
            pid for pid in initial_pids if os.path.exists("/proc/%s" % pid)
        ]
        logger.debug("running_processes: %s, cycles: %s", running_processes,
                     num_cycles)

        for pid in running_processes:
            logger.debug(Process(pid))

        if not running_processes:
            logger.debug("Done in %s cycles", num_cycles)
            break
        if num_cycles > 300:
            logger.warning("Some wine processes are still running: %s",
                           ', '.join(running_processes))
            break
        time.sleep(0.1)
예제 #5
0
파일: thread.py 프로젝트: steevp/lutris
    def watch_children(self):
        """Poke at the running process(es)."""
        if not self.game_process:
            logger.error('No game process available')
            return False
        process = Process(self.rootpid)
        num_children = 0
        num_watched_children = 0
        terminated_children = 0
        passed_terminal_procs = False
        for child in self.iter_children(process):
            # Exclude terminal processes
            if self.terminal:
                if child.name == "run_in_term.sh":
                    passed_terminal_procs = True
                if not passed_terminal_procs:
                    continue

            num_children += 1
            if child.name in EXCLUDED_PROCESSES:
                logger.debug("Excluding %s from process monitor" % child.name)
                continue
            num_watched_children += 1
            logger.debug("{}\t{}\t{}".format(child.pid, child.state,
                                             child.name))
            if child.state == 'Z':
                terminated_children += 1

        if num_watched_children > 0 and not self.monitoring_started:
            self.monitoring_started = True

        if self.runner and hasattr(self.runner, 'watch_game_process'):
            if not self.runner.watch_game_process():
                self.is_running = False
                return False
        if num_watched_children == 0:
            time_since_start = time.time() - self.startup_time
            if self.monitoring_started or time_since_start > WARMUP_TIME:
                self.cycles_without_children += 1
        max_cycles_reached = (self.cycles_without_children >=
                              self.max_cycles_without_children)
        if num_children == 0 or max_cycles_reached:
            if max_cycles_reached:
                logger.debug(
                    'Maximum number of cycles without children reached')
            self.is_running = False
            self.stop()
            if num_children == 0:
                logger.debug("No children left in thread")
                self.game_process.communicate()
            else:
                logger.debug('Some processes are still active (%d)',
                             num_children)
            self.return_code = self.game_process.returncode
            return False
        if terminated_children and terminated_children == num_watched_children:
            logger.debug("All children terminated")
            self.game_process.wait()
        return True
예제 #6
0
 def killall(self):
     """Kill every remaining child process"""
     killed_processes = []
     for process in self.iter_children(Process(self.rootpid),
                                       topdown=False):
         killed_processes.append(str(process))
         process.kill()
     if killed_processes:
         logger.debug("Killed processes: %s", ', '.join(killed_processes))
예제 #7
0
파일: thread.py 프로젝트: ERIIX/lutris
 def stop(self, killall=False):
     for thread in self.attached_threads:
         thread.stop()
     if hasattr(self, 'stop_func'):
         self.stop_func()
         if not killall:
             return
     for process in self.iter_children(Process(self.rootpid),
                                       topdown=False):
         process.kill()
예제 #8
0
파일: thread.py 프로젝트: ERIIX/lutris
 def iter_children(self, process, topdown=True, first=True):
     if self.runner.name.startswith('wine') and first:
         pids = self.runner.get_pids()
         for pid in pids:
             wineprocess = Process(pid)
             if wineprocess.name not in self.runner.core_processes:
                 process.children.append(wineprocess)
     for child in process.children:
         if topdown:
             yield child
         subs = self.iter_children(child, topdown=topdown, first=False)
         for sub in subs:
             yield sub
         if not topdown:
             yield child
예제 #9
0
 def iter_children(self, process, topdown=True, first=True):
     if self.runner and self.runner.name.startswith('wine') and first:
         if 'WINE' in self.env:
             # Track the correct version of wine for winetricks
             wine_version = self.env['WINE']
         else:
             wine_version = None
         pids = self.runner.get_pids(wine_version)
         for pid in pids:
             wineprocess = Process(pid)
             if wineprocess.name not in self.runner.core_processes:
                 process.children.append(wineprocess)
     for child in process.children:
         if topdown:
             yield child
         subs = self.iter_children(child, topdown=topdown, first=False)
         for sub in subs:
             yield sub
         if not topdown:
             yield child
예제 #10
0
파일: thread.py 프로젝트: ERIIX/lutris
 def watch_children(self):
     """pokes at the running process"""
     process = Process(self.rootpid)
     num_children = 0
     num_watched_children = 0
     terminated_children = 0
     for child in self.iter_children(process):
         num_children += 1
         if child.name in ('steamwebhelper', 'steam', 'sh', 'tee', 'bash'):
             continue
         num_watched_children += 1
         print "{}\t{}\t{}".format(child.pid, child.state, child.name)
         if child.state == 'Z':
             terminated_children += 1
     if terminated_children and terminated_children == num_watched_children:
         self.game_process.wait()
     if num_watched_children == 0:
         self.cycles_without_children += 1
     if num_children == 0 or self.cycles_without_children >= 3:
         self.is_running = False
         return False
     return True
예제 #11
0
파일: thread.py 프로젝트: notjuliee/lutris
    def watch_children(self):
        """Poke at the running process(es)."""
        if not self.game_process:
            logger.error('No game process available')
            return False
        process = Process(self.rootpid)
        num_children = 0
        num_watched_children = 0
        terminated_children = 0
        passed_terminal_procs = False
        processes = defaultdict(list)
        for child in self.iter_children(process):
            # Exclude terminal processes
            if self.terminal:
                if child.name == "run_in_term.sh":
                    passed_terminal_procs = True
                if not passed_terminal_procs:
                    continue

            num_children += 1
            if child.pid in self.old_pids:
                processes['external'].append(str(child))
                continue
            if child.name in EXCLUDED_PROCESSES and child.name not in self.include_processes:
                processes['excluded'].append(str(child))
                continue
            num_watched_children += 1
            processes['monitored'].append(str(child))
            if child.state == 'Z':
                terminated_children += 1

        logger.debug("Processes: " + " | ".join([
            "{}: {}".format(key, ', '.join(processes[key]))
            for key in processes if processes[key]
        ]))

        if num_watched_children > 0 and not self.monitoring_started:
            self.monitoring_started = True

        if self.runner and hasattr(self.runner, 'watch_game_process'):
            if not self.runner.watch_game_process():
                self.is_running = False
                return False
        if num_watched_children == 0:
            time_since_start = time.time() - self.startup_time
            if self.monitoring_started or time_since_start > WARMUP_TIME:
                self.cycles_without_children += 1
        max_cycles_reached = (self.cycles_without_children >=
                              MAX_CYCLES_WITHOUT_CHILDREN)
        if num_children == 0 or max_cycles_reached:
            if max_cycles_reached:
                logger.debug(
                    'Maximum number of cycles without children reached')
            self.is_running = False
            self.stop()
            if num_children == 0:
                logger.debug("No children left in thread")
                self.game_process.communicate()
            else:
                logger.debug('Some processes are still active (%d)',
                             num_children)
            self.return_code = self.game_process.returncode
            if self.stdout_monitor:
                GLib.source_remove(self.stdout_monitor)
            return False
        if terminated_children and terminated_children == num_watched_children:
            logger.debug("All children terminated")
            self.game_process.wait()
            if self.stdout_monitor:
                GLib.source_remove(self.stdout_monitor)
            self.is_running = False
            return False
        return True
예제 #12
0
파일: thread.py 프로젝트: notjuliee/lutris
 def killall(self):
     for process in self.iter_children(Process(self.rootpid),
                                       topdown=False):
         logger.debug("Killing process %s", process)
         process.kill()
예제 #13
0
 def iterate_all_processes(self):
     return Process(os.getpid()).iter_children()
예제 #14
0
 def iterate_children():
     """Iterates through all children process of the lutris client.
     This is not accurate since not all processes are started by
     lutris but are started by Systemd instead.
     """
     return Process(os.getpid()).iter_children()