Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attempt to remove all gdk threads_enter and leave calls #129

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ nobase_pkgdata_DATA= \
smburi.py \
statereason.py \
timedops.py \
thread_operations.py \
ToolbarSearchEntry.py \
userdefault.py \
ui/AboutDialog.ui \
Expand Down
113 changes: 53 additions & 60 deletions system-config-printer.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,8 @@

# config is generated from config.py.in by configure
import config

import sys, os, time, re
import _thread
import threading
import dbus
import gi
try:
Expand Down Expand Up @@ -94,6 +93,7 @@ def show_help():
import newprinter
from newprinter import busy, ready
import printerproperties
from thread_operations import thread_safe_blocking_call, SCP_MAIN_THREAD_NAME

import ppdippstr
ppdippstr.init ()
Expand Down Expand Up @@ -749,6 +749,7 @@ def on_server_settings_activate (self, menuitem):
except RuntimeError:
self.monitor.update ()

@thread_safe_blocking_call
def setConnected(self):
connected = bool(self.cups)

Expand Down Expand Up @@ -830,6 +831,7 @@ def getServers(self):
known_servers.sort()
return known_servers

@thread_safe_blocking_call
def populateList(self, prompt_allowed=True):
# Save selection of printers.
selected_printers = set()
Expand Down Expand Up @@ -1178,19 +1180,17 @@ def on_connect_activate(self, widget):
cups.setUser('')
self.connect_user = cups.getUser()
# Now start a new thread for connection.
self.connect_thread = _thread.start_new_thread(self.connect,
(self.PrintersWindow,))
self.connect_thread = threading.Thread(target=self.connect,
name="SCP_CONNECTING_THREAD"
)
self.connect_thread.start()

def update_connecting_pbar (self):
ret = True
Gdk.threads_enter ()
try:
if not self.ConnectingDialog.get_property ("visible"):
ret = False # stop animation
else:
self.pbarConnecting.pulse ()
finally:
Gdk.threads_leave ()
if not self.ConnectingDialog.get_property ("visible"):
ret = False # stop animation
else:
self.pbarConnecting.pulse ()

return ret

Expand All @@ -1207,7 +1207,7 @@ def on_cancel_connect_clicked(self, widget):
self.connect_thread = None
self.ConnectingDialog.hide()

def connect(self, parent=None):
def connect(self):
"""
Open a connection to a new server. Is executed in a separate thread!
"""
Expand All @@ -1232,42 +1232,44 @@ def connect(self, parent=None):
nonfatalException ()

try:
connection = authconn.Connection(parent,
connection = authconn.Connection(self.PrintersWindow,
host=self.connect_server,
encryption=self.connect_encrypt)
except RuntimeError as s:
if self.connect_thread != _thread.get_ident(): return
Gdk.threads_enter()
try:
self.ConnectingDialog.hide()
self.cups = None
self.setConnected()
self.populateList()
show_IPP_Error(None, s, parent)
finally:
Gdk.threads_leave()
if self.connect_thread != threading.currentThread(): return
Gdk.threads_add_idle(GLib.PRIORITY_DEFAULT_IDLE,
self.ConnectingDialog.hide,
)
self.cups = None
self.setConnected()
self.populateList()
Gdk.threads_add_idle(GLib.PRIORITY_DEFAULT_IDLE,
show_IPP_Error,
None, s, self.PrintersWindow
)
return
except cups.IPPError as e:
(e, s) = e.args
if self.connect_thread != _thread.get_ident(): return
Gdk.threads_enter()
try:
self.ConnectingDialog.hide()
self.cups = None
self.setConnected()
self.populateList()
show_IPP_Error(e, s, parent)
finally:
Gdk.threads_leave()
if self.connect_thread != threading.currentThread(): return
Gdk.threads_add_idle(GLib.PRIORITY_DEFAULT_IDLE,
self.ConnectingDialog.hide,
)
self.cups = None
self.setConnected()
self.populateList()
Gdk.threads_add_idle(GLib.PRIORITY_DEFAULT_IDLE,
show_IPP_Error,
None, s, self.PrintersWindow
)
return
except:
nonfatalException ()

if self.connect_thread != _thread.get_ident(): return
Gdk.threads_enter()

if self.connect_thread != threading.currentThread(): return
try:
self.ConnectingDialog.hide()
Gdk.threads_add_idle(GLib.PRIORITY_DEFAULT_IDLE,
self.ConnectingDialog.hide,
)
self.cups = connection
self.setConnected()
self.populateList()
Expand All @@ -1276,12 +1278,13 @@ def connect(self, parent=None):
self.cups = None
self.setConnected()
self.populateList()
show_HTTP_Error(s, parent)
Gdk.threads_add_idle(GLib.PRIORITY_DEFAULT_IDLE,
show_HTTP_Error,
s, self.PrintersWindow
)
except:
nonfatalException ()

Gdk.threads_leave()

def reconnect (self):
"""Reconnect to CUPS after the server has reloaded."""
# libcups would handle the reconnection if we just told it to
Expand Down Expand Up @@ -2058,23 +2061,19 @@ def on_start_service_reply (self, *args):
GLib.timeout_add_seconds (1, self.service_started_try)

def service_started_try (self):
Gdk.threads_enter ()
try:
self.on_btnRefresh_clicked (None)
finally:
Gdk.threads_leave ()
Gdk.threads_add_idle(GLib.PRIORITY_DEFAULT_IDLE,
self.on_btnRefresh_clicked,
None
)


GLib.timeout_add_seconds (1, self.service_started_retry)
return False

def service_started_retry (self):
if not self.cups:
Gdk.threads_enter ()
try:
self.on_btnRefresh_clicked (None)
self.btnStartService.set_sensitive (True)
finally:
Gdk.threads_leave ()

return False

Expand Down Expand Up @@ -2180,11 +2179,7 @@ def on_printer_modified (self, obj, name, ppd_has_changed):
def defer_refresh (self):
def deferred_refresh ():
self.populateList_timer = None
Gdk.threads_enter ()
try:
self.populateList (prompt_allowed=False)
finally:
Gdk.threads_leave ()
self.populateList (prompt_allowed=False)
return False

if self.populateList_timer:
Expand Down Expand Up @@ -2222,6 +2217,8 @@ def cups_connection_recovered (self, mon):

def main(show_jobs):
cups.setUser (os.environ.get ("CUPS_USER", cups.getUser()))
# set name for main thread
threading.currentThread().setName(SCP_MAIN_THREAD_NAME)
Gdk.threads_init ()
from dbus.glib import DBusGMainLoop
DBusGMainLoop (set_as_default=True)
Expand All @@ -2233,11 +2230,7 @@ def main(show_jobs):
else:
mainwindow = GUI()

Gdk.threads_enter ()
try:
Gtk.main()
finally:
Gdk.threads_leave ()
Gtk.main()

if __name__ == "__main__":
import getopt
Expand Down
30 changes: 30 additions & 0 deletions thread_operations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import threading
gi.require_version('Gdk', '3.0')
from gi.repository import Gdk, GLib

SCP_MAIN_THREAD_NAME = "SCP_MAIN_THREAD"

def thread_safe_blocking_call(function):
""" Make function/method thread safe and block until its call is finished
"""

blocker = threading.Event()

def inner_wrapper(*args, **kwargs):
function(*args, **kwargs)
blocker.set()
return False

def wrapper(*args, **kwargs):
# if this is the main thread then simply return function
if threading.current_thread().name == SCP_MAIN_THREAD_NAME:
return function(*args, **kwargs)
Gdk.threads_add_idle(
GLib.PRIORITY_DEFAULT_IDLE,
inner_wrapper,
*args,
**kwargs
)
blocker.wait()

return wrapper