mirror of
https://github.com/lutris/lutris
synced 2024-09-15 22:09:55 +00:00
Monitor wine processes
This commit is contained in:
parent
5d3b1f3666
commit
dabd331d8f
|
@ -198,7 +198,7 @@ class Game(object):
|
|||
self.killswitch = None
|
||||
|
||||
self.game_thread = LutrisThread(launch_arguments,
|
||||
path=self.runner.working_dir, env=env,
|
||||
runner=self.runner, env=env,
|
||||
rootpid=gameplay_info.get('rootpid'))
|
||||
self.state = self.STATE_RUNNING
|
||||
if hasattr(self.runner, 'stop'):
|
||||
|
|
|
@ -199,5 +199,5 @@ class steam(Runner):
|
|||
appid = self.game_config.get('appid')
|
||||
logger.debug("Launching Wine Steam uninstall of game %s" % appid)
|
||||
command = '"%s" steam://uninstall/%s' % (self.steam_exe, appid)
|
||||
thread = LutrisThread(command, path=self.working_dir)
|
||||
thread = LutrisThread(command, runner=self)
|
||||
thread.start()
|
||||
|
|
|
@ -203,7 +203,6 @@ def is_version_installed(version, arch=None):
|
|||
class wine(Runner):
|
||||
"""Run Windows games with Wine."""
|
||||
human_name = "Wine"
|
||||
executable = 'wine'
|
||||
platform = 'Windows'
|
||||
game_options = [
|
||||
{
|
||||
|
@ -262,6 +261,14 @@ class wine(Runner):
|
|||
"Desktop": r"%s\Explorer" % reg_prefix
|
||||
}
|
||||
|
||||
core_processes = (
|
||||
'services.exe',
|
||||
'winedevice.exe',
|
||||
'plugplay.exe',
|
||||
'explorer.exe',
|
||||
'rpcss.exe',
|
||||
)
|
||||
|
||||
def __init__(self, config=None):
|
||||
super(wine, self).__init__(config)
|
||||
wine_versions = \
|
||||
|
@ -510,6 +517,13 @@ class wine(Runner):
|
|||
env['WINEPREFIX'] = self.prefix_path
|
||||
return env
|
||||
|
||||
def get_pids(self):
|
||||
"""Return a list of pids of processes using the current wine exe"""
|
||||
exe = self.get_executable()
|
||||
if not exe.startswith('/'):
|
||||
exe = system.find_executable(exe)
|
||||
return system.get_pids_using_file(exe)
|
||||
|
||||
def play(self):
|
||||
game_exe = self.game_exe
|
||||
arguments = self.game_config.get('args') or ''
|
||||
|
|
|
@ -336,5 +336,5 @@ class winesteam(wine.wine):
|
|||
env = self.get_env()
|
||||
command = self.launch_args + ['steam://uninstall/%s' % appid]
|
||||
self.prepare_launch()
|
||||
thread = LutrisThread(' '.join(command), path=self.working_dir, env=env)
|
||||
thread = LutrisThread(' '.join(command), runner=self, env=env)
|
||||
thread.start()
|
||||
|
|
|
@ -16,12 +16,14 @@ HEARTBEAT_DELAY = 5000 # Number of milliseconds between each heartbeat
|
|||
|
||||
class LutrisThread(threading.Thread):
|
||||
"""Runs the game in a separate thread"""
|
||||
def __init__(self, command, path="/tmp", env={}, rootpid=None):
|
||||
debug_output = False
|
||||
|
||||
def __init__(self, command, runner=None, env={}, rootpid=None):
|
||||
"""Thread init"""
|
||||
threading.Thread.__init__(self)
|
||||
self.env = env
|
||||
self.command = command
|
||||
self.path = path
|
||||
self.runner = runner
|
||||
self.game_process = None
|
||||
self.return_code = None
|
||||
self.rootpid = rootpid or os.getpid()
|
||||
|
@ -29,7 +31,11 @@ class LutrisThread(threading.Thread):
|
|||
self.stdout = ''
|
||||
self.attached_threads = []
|
||||
self.cycles_without_children = 0
|
||||
logger.debug('Running thread from %s', self.path)
|
||||
|
||||
if self.runner:
|
||||
self.path = runner.working_dir
|
||||
else:
|
||||
self.path = '/tmp/'
|
||||
|
||||
def attach_thread(self, thread):
|
||||
"""Attach child process that need to be killed on game exit"""
|
||||
|
@ -45,15 +51,22 @@ class LutrisThread(threading.Thread):
|
|||
cwd=self.path, env=self.env)
|
||||
for line in iter(self.game_process.stdout.readline, ''):
|
||||
self.stdout += line
|
||||
sys.stdout.write(line)
|
||||
if self.debug_output:
|
||||
sys.stdout.write(line)
|
||||
|
||||
def iter_children(self, process, topdown=True):
|
||||
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
|
||||
gen = self.iter_children(child)
|
||||
for c in gen:
|
||||
yield c
|
||||
subs = self.iter_children(child, topdown=topdown, first=False)
|
||||
for sub in subs:
|
||||
yield sub
|
||||
if not topdown:
|
||||
yield child
|
||||
|
||||
|
|
|
@ -174,8 +174,8 @@ def get_pids_using_file(path):
|
|||
"""Return a list of pids using file `path`"""
|
||||
if not os.path.exists(path):
|
||||
logger.error("No file %s", path)
|
||||
return
|
||||
lsof_output = execute("lsof -t \"{}\"".format(path))
|
||||
return []
|
||||
lsof_output = execute(["lsof", "-t", path])
|
||||
if lsof_output:
|
||||
return lsof_output.split('\n')
|
||||
else:
|
||||
|
|
Loading…
Reference in a new issue