don't freeze gui during long makepkg tasks and avoid zombis with pamac-tray

This commit is contained in:
guinux 2013-11-27 16:11:47 +01:00
parent 3b4a29bcf9
commit 10c2dfebd5
2 changed files with 31 additions and 23 deletions

View File

@ -19,9 +19,10 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
from gi.repository import Gtk, GObject, Notify
from subprocess import Popen
from subprocess import call
import dbus
from dbus.mainloop.glib import DBusGMainLoop
from threading import Thread
from pamac import common
@ -64,10 +65,10 @@ class Tray:
self.update_icon(icon, info)
def execute_update(self, widget, event, data = None):
Popen(['/usr/bin/pamac-updater'])
Thread(target = call, args = (['/usr/bin/pamac-updater'],)).start()
def execute_manager(self, widget, event, data = None):
Popen(['/usr/bin/pamac-manager'])
Thread(target = call, args = (['/usr/bin/pamac-manager'],)).start()
def quit_tray(self, widget, data = None):
Gtk.main_quit()
@ -80,7 +81,7 @@ class Tray:
def activate_cb(self, widget, data = None):
if icon == update_icon:
Popen(['/usr/bin/pamac-updater'])
Thread(target = call, args = (['/usr/bin/pamac-updater'],)).start()
def update_icon(self, icon, info):
self.statusIcon.set_from_file(icon)
@ -90,7 +91,7 @@ class Tray:
self.statusIcon.set_visible(boolean)
def refresh():
Popen(['/usr/bin/pamac-refresh'])
Thread(target = call, args = (['/usr/bin/pamac-refresh'],)).start()
def set_icon(update_data):
global icon

View File

@ -29,6 +29,7 @@ import fnmatch
#from urllib.parse import urlparse
import dbus
from dbus.mainloop.glib import DBusGMainLoop
import signal
from pamac import config, common, aur
@ -134,18 +135,6 @@ def config_dbus_signals():
bus.add_signal_receiver(log_error, dbus_interface = "org.manjaro.pamac", signal_name = "EmitLogError")
bus.add_signal_receiver(log_warning, dbus_interface = "org.manjaro.pamac", signal_name = "EmitLogWarning")
def write_to_buffer(fd, condition):
if condition == GObject.IO_IN: # if there's something interesting to read
line = fd.readline().decode(encoding='UTF-8')
#print(line.rstrip('\n'))
progress_buffer.insert_at_cursor(line)
progress_bar.pulse()
while Gtk.events_pending():
Gtk.main_iteration()
return True # FUNDAMENTAL, otherwise the callback isn't recalled
else:
return False # Raised an error: exit
def action_handler(action):
progress_label.set_text(action)
@ -468,16 +457,34 @@ def prepare(**trans_flags):
return(error)
def check_finished_build(data):
def handle_timeout(*args):
raise Exception('timeout')
global to_build
global build_proc
path = data[0]
pkg = data[1]
if build_proc.poll() is None:
progress_bar.pulse()
while Gtk.events_pending():
Gtk.main_iteration()
return True
# Build no finished : read stdout to push it to text_buffer
# add a timeout to stop reading stdout if too long
# so the gui won't freeze
signal.signal(signal.SIGALRM, handle_timeout)
signal.setitimer(signal.ITIMER_REAL, 0.05) # 50 ms timeout
try:
line = build_proc.stdout.readline().decode(encoding='UTF-8')
#print(line.rstrip('\n'))
progress_buffer.insert_at_cursor(line)
progress_bar.pulse()
while Gtk.events_pending():
Gtk.main_iteration()
except Exception:
while Gtk.events_pending():
Gtk.main_iteration()
finally:
signal.alarm(0)
return True
elif build_proc.poll() == 0:
# Build successfully finished
built = []
# parse again PKGBUILD to have new pkg objects in case of a pkgver() function
# was used so pkgver was changed during build process
@ -525,6 +532,7 @@ def check_finished_build(data):
action_long_handler(_('Build process failed.'))
return False
elif build_proc.poll() == 1:
# Build finish with an error
ProgressCancelButton.set_visible(False)
ProgressCloseButton.set_visible(True)
action_long_handler(_('Build process failed.'))
@ -625,10 +633,9 @@ def build_next():
progress_expander.set_expanded(True)
ProgressWindow.show()
build_proc = subprocess.Popen(["makepkg", "-cf"], cwd = path, stdout = subprocess.PIPE, stderr=subprocess.STDOUT)
GObject.io_add_watch(build_proc.stdout, GObject.IO_IN, write_to_buffer)
while Gtk.events_pending():
Gtk.main_iteration()
GObject.timeout_add(500, check_finished_build, (path, pkg))
GObject.timeout_add(100, check_finished_build, (path, pkg))
def finalize():
if To_Add() or To_Remove():