[PATCH 2/3] Remove Gdk thread initialization, introduce new helper functions and make exception handler be called by Gtk only once

Martin Sivak msivak at redhat.com
Tue Oct 16 14:36:51 UTC 2012


This patch is a prelude to the big threading move from the gdk_threads_enter/leave to
the GLib.idle_add style.

It introduces all the new helper functions and removes Gdk threads completely.
---
 pyanaconda/__init__.py     |  3 ---
 pyanaconda/exception.py    |  3 ++-
 pyanaconda/ui/gui/utils.py | 67 +++++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 62 insertions(+), 11 deletions(-)

diff --git a/pyanaconda/__init__.py b/pyanaconda/__init__.py
index c46d20c..4844f00 100644
--- a/pyanaconda/__init__.py
+++ b/pyanaconda/__init__.py
@@ -211,9 +211,6 @@ class Anaconda(object):
             raise RuntimeError, "Second attempt to initialize the InstallInterface"
 
         if self.displayMode == 'g':
-            from gi.repository import Gdk
-            Gdk.threads_init()
-
             from pyanaconda.ui.gui import GraphicalUserInterface
             self._intf = GraphicalUserInterface(self.storage, self.payload,
                                                 self.instClass)
diff --git a/pyanaconda/exception.py b/pyanaconda/exception.py
index 4e369d8..94adf82 100644
--- a/pyanaconda/exception.py
+++ b/pyanaconda/exception.py
@@ -59,7 +59,8 @@ class AnacondaExceptionHandler(ExceptionHandler):
 
             super(AnacondaExceptionHandler, self).handleException((ty, value, tb),
                                                                   obj)
-
+            return False
+            
         if issubclass(ty, storage.errors.StorageError) and value.hardware_fault:
             hw_error_msg = _("The installation was stopped due to what "
                              "seems to be a problem with your hardware. "
diff --git a/pyanaconda/ui/gui/utils.py b/pyanaconda/ui/gui/utils.py
index fcd0f76..10ad1df 100644
--- a/pyanaconda/ui/gui/utils.py
+++ b/pyanaconda/ui/gui/utils.py
@@ -19,7 +19,66 @@
 # Red Hat Author(s): Chris Lumens <clumens at redhat.com>
 #
 from contextlib import contextmanager
-from gi.repository import Gdk, Gtk
+from gi.repository import Gdk, Gtk, GLib
+import Queue
+
+def gtk_call_once(func, *args):
+    """Wrapper for GLib.idle_add call that ensures the func is called
+       only once.
+    """ 
+    def wrap(args):
+        func(*args)
+        return False
+    
+    GLib.idle_add(wrap, args)
+
+def gtk_thread_wait(func):
+    """Decorator method which causes every call of the decorated function
+       to be executed in the context of Gtk main loop and returns the ret
+       value after the decorated method finishes.
+
+       Method decorated by this decorator must not be called from inside
+       of the Gtk main loop. It will cause a hang.
+    """
+    queue = Queue.Queue()
+
+    def _idle_method(q_args):
+        """This method contains the code for the main loop to execute.
+        """
+        queue, args = q_args
+        ret = func(*args)
+        queue.put(ret)
+        return False
+
+    def _call_method(*args):
+        """The new body for the decorated method. It uses closure bound
+           queue variable which is valid until the reference to this method
+           is destroyed."""
+        GLib.idle_add(_idle_method, (queue, args))
+        return queue.get()
+
+    return _call_method
+
+
+def gtk_thread_nowait(func):
+    """Decorator method which causes every call of the decorated function
+       to be executed in the context of Gtk main loop. The new method does
+       not wait for the callback to finish.
+    """
+
+    def _idle_method(args):
+        """This method contains the code for the main loop to execute.
+        """
+        ret = func(*args)
+        return False
+
+    def _call_method(*args):
+        """The new body for the decorated method.
+        """
+        GLib.idle_add(_idle_method, args)
+
+    return _call_method
+
 
 @contextmanager
 def enlightbox(mainWindow, dialog):
@@ -29,12 +88,6 @@ def enlightbox(mainWindow, dialog):
     yield
     lightbox.destroy()
 
- at contextmanager
-def gdk_threaded():
-    Gdk.threads_enter()
-    yield
-    Gdk.threads_leave()
-
 def setViewportBackground(vp, color="@theme_bg_color"):
     """Set the background color of the GtkViewport vp to be the same as the
        overall UI background.  This should not be called for every viewport,
-- 
1.7.11.4



More information about the anaconda-patches mailing list