[fix regression] Remove psutil, it could cause Lutris to slow down while game is running

This commit is contained in:
daniel-j 2017-09-04 11:12:58 +02:00 committed by djazz
parent 8a566ebb84
commit 85f3d893e2
8 changed files with 69 additions and 46 deletions

View file

@ -12,6 +12,6 @@ before_install:
install: install:
- pip install --upgrade pip - pip install --upgrade pip
- sudo apt-get -qq update - sudo apt-get -qq update
- sudo apt-get install -y python3-yaml python3-psutil python3-gi gir1.2-gtk-3.0 psmisc gir1.2-glib-2.0 libgirepository1.0-dev - sudo apt-get install -y python3-yaml python3-gi gir1.2-gtk-3.0 psmisc gir1.2-glib-2.0 libgirepository1.0-dev
script: nosetests script: nosetests

View file

@ -8,8 +8,7 @@ Lutris should work on any Gnome system, the following depencies should be
installed: installed:
* python > 3.4 * python > 3.4
* python3-yaml * python-yaml
* python3-psutil
* PyGobject * PyGobject
* libsoup-gnome * libsoup-gnome

1
debian/control vendored
View file

@ -20,7 +20,6 @@ Architecture: any
Depends: ${misc:Depends}, Depends: ${misc:Depends},
${python3:Depends}, ${python3:Depends},
python3-yaml, python3-yaml,
python3-psutil,
python3-gi, python3-gi,
gir1.2-gtk-3.0, gir1.2-gtk-3.0,
psmisc, psmisc,

View file

@ -21,11 +21,11 @@ BuildRequires: python3-devel
%if 0%{?fedora_version} %if 0%{?fedora_version}
BuildRequires: python3-gobject, python3-wheel, python3-setuptools, python3-gobject BuildRequires: python3-gobject, python3-wheel, python3-setuptools, python3-gobject
Requires: python3-gobject, python3-PyYAML, python3-psutil, cabextract Requires: python3-gobject, python3-PyYAML, cabextract
%endif %endif
%if 0%{?rhel_version} || 0%{?centos_version} %if 0%{?rhel_version} || 0%{?centos_version}
BuildRequires: python3-gobject BuildRequires: python3-gobject
Requires: python3-gobject, python3-PyYAML, python3-psutil, cabextract Requires: python3-gobject, python3-PyYAML, cabextract
%endif %endif
%if 0%{?suse_version} %if 0%{?suse_version}
BuildRequires: python3-gobject BuildRequires: python3-gobject
@ -34,7 +34,7 @@ BuildRequires: update-desktop-files
BuildRequires: hicolor-icon-theme BuildRequires: hicolor-icon-theme
BuildRequires: polkit BuildRequires: polkit
BuildRequires: python3-setuptools BuildRequires: python3-setuptools
Requires: python3-gobject, python3-PyYAML, python3-psutil, cabextract Requires: python3-gobject, python3-PyYAML, cabextract
%endif %endif
%if 0%{?fedora_version} || 0%{?suse_version} %if 0%{?fedora_version} || 0%{?suse_version}
BuildRequires: fdupes BuildRequires: fdupes

View file

@ -4,7 +4,6 @@ import os
import time import time
import shlex import shlex
import subprocess import subprocess
import psutil
from lutris import settings from lutris import settings
from lutris.gui.dialogs import DownloadDialog from lutris.gui.dialogs import DownloadDialog
@ -38,7 +37,7 @@ def is_running():
if pid: if pid:
# If process is defunct, don't consider it as running # If process is defunct, don't consider it as running
process = Process(pid) process = Process(pid)
return process.state != psutil.STATUS_ZOMBIE return process.state != 'Z'
else: else:
return False return False

View file

@ -8,7 +8,6 @@ import shlex
import threading import threading
import subprocess import subprocess
import contextlib import contextlib
import psutil
from collections import defaultdict from collections import defaultdict
from gi.repository import GLib from gi.repository import GLib
@ -259,7 +258,7 @@ class LutrisThread(threading.Thread):
continue continue
num_watched_children += 1 num_watched_children += 1
processes['monitored'].append(str(child)) processes['monitored'].append(str(child))
if child.state == psutil.STATUS_ZOMBIE: if child.state == 'Z':
terminated_children += 1 terminated_children += 1
if processes != self.monitored_processes: if processes != self.monitored_processes:

View file

@ -1,5 +1,5 @@
import os import os
import psutil import signal
from lutris.util.log import logger from lutris.util.log import logger
@ -13,39 +13,48 @@ class Process(object):
self.pid = int(pid) self.pid = int(pid)
except ValueError: except ValueError:
raise InvalidPid("'%s' is not a valid pid" % pid) raise InvalidPid("'%s' is not a valid pid" % pid)
self.process = None
self.children = [] self.children = []
self.children_pids = []
self.parent = None self.parent = None
try:
self.process = psutil.Process(self.pid)
except psutil.NoSuchProcess:
return
self.get_children() self.get_children()
def __repr__(self): def __repr__(self):
return "Process {}".format(self.pid) return "Process {}".format(self.pid)
def __str__(self): def __str__(self):
if self.process and self.process.is_running(): return "{} ({}:{})".format(self.name, self.pid, self.state)
return "{} ({}:{})".format(self.name, self.pid, self.state)
return str(self.pid) def get_stat(self, parsed=True):
stat_filename = "/proc/{}/stat".format(self.pid)
if not os.path.exists(stat_filename):
return
with open(stat_filename) as stat_file:
try:
_stat = stat_file.readline()
except (ProcessLookupError, FileNotFoundError):
logger.warning('Unable to read stat for process %s', self.pid)
return
if parsed:
return _stat[_stat.rfind(")") + 1:].split()
return _stat
def get_thread_ids(self): def get_thread_ids(self):
"""Return a list of thread ids opened by process.""" """Return a list of thread ids opened by process."""
if self.process and self.process.is_running(): basedir = '/proc/{}/task/'.format(self.pid)
return [c.id for c in self.process.threads()] if os.path.isdir(basedir):
try:
return [tid for tid in os.listdir(basedir)]
except FileNotFoundError:
return []
else: else:
return [] return []
def get_children_pids_of_thread(self, tid): def get_children_pids_of_thread(self, tid):
"""Return pids of child processes opened by thread `tid` of process.""" """Return pids of child processes opened by thread `tid` of process."""
children = [] children = []
try: children_path = '/proc/{}/task/{}/children'.format(self.pid, tid)
p = psutil.Process(tid) if os.path.exists(children_path):
children = [c.pid for c in p.children()] with open(children_path) as children_file:
except: children = children_file.read().strip().split()
pass
return children return children
def get_children(self): def get_children(self):
@ -57,8 +66,9 @@ class Process(object):
@property @property
def name(self): def name(self):
"""Filename of the executable.""" """Filename of the executable."""
if self.process and self.process.is_running(): _stat = self.get_stat(parsed=False)
return self.process.name() if _stat:
return _stat[_stat.find("(") + 1:_stat.rfind(")")]
@property @property
def state(self): def state(self):
@ -67,24 +77,39 @@ class Process(object):
sleep, Z is zombie, T is traced or stopped (on a signal), and W is sleep, Z is zombie, T is traced or stopped (on a signal), and W is
paging. paging.
""" """
if self.process and self.process.is_running(): _stat = self.get_stat()
return self.process.status() if _stat:
return psutil.STATUS_ZOMBIE return _stat[0]
@property
def ppid(self):
"""PID of the parent."""
_stat = self.get_stat()
if _stat:
return _stat[1]
@property
def pgrp(self):
"""Process group ID of the process."""
_stat = self.get_stat()
if _stat:
return _stat[2]
@property @property
def cmdline(self): def cmdline(self):
"""Return command line used to run the process `pid`.""" """Return command line used to run the process `pid`."""
if self.process and self.process.is_running(): cmdline_path = '/proc/{}/cmdline'.format(self.pid)
return self.process.cmdline() with open(cmdline_path) as cmdline_file:
_cmdline = cmdline_file.read().replace('\x00', ' ')
return _cmdline
@property @property
def cwd(self): def cwd(self):
if self.process and self.process.is_running(): cwd_path = '/proc/%d/cwd' % int(self.pid)
cwd_path = self.process.cwd() return os.readlink(cwd_path)
return os.readlink(cwd_path)
def kill(self): def kill(self):
try: try:
self.process.kill() os.kill(self.pid, signal.SIGKILL)
except OSError: except OSError:
logger.error("Could not kill process %s", self.pid) logger.error("Could not kill process %s", self.pid)

View file

@ -6,7 +6,6 @@ import string
import subprocess import subprocess
import sys import sys
import traceback import traceback
import psutil
from lutris.util.log import logger from lutris.util.log import logger
@ -138,7 +137,7 @@ def get_pid(program, multiple=False):
def get_all_pids(): def get_all_pids():
"""Return all pids of currently running processes""" """Return all pids of currently running processes"""
return psutil.pids() return [int(pid) for pid in os.listdir('/proc') if pid.isdigit()]
def kill_pid(pid): def kill_pid(pid):
@ -147,15 +146,18 @@ def kill_pid(pid):
except ValueError: except ValueError:
logger.error("Invalid pid %s") logger.error("Invalid pid %s")
return return
psutil.Process(pid).kill() execute(['kill', '-9', pid])
def get_command_line(pid): def get_command_line(pid):
"""Return command line used to run the process `pid`.""" """Return command line used to run the process `pid`."""
try: cmdline = None
return psutil.Process(pid).cmdline() cmdline_path = '/proc/{}/cmdline'.format(pid)
except: if os.path.exists(cmdline_path):
pass with open(cmdline_path) as cmdline_file:
cmdline = cmdline_file.read()
cmdline = cmdline.replace('\x00', ' ')
return cmdline
def python_identifier(string): def python_identifier(string):