[rhel6-branch] Block button handlers after a button is pressed (#738217)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



There's a race condition if the buttons are pressed almost
simultaneously, causing more dialogs to appear at the same time.
Although all the dialogs are modal, gtk doesn't make the buttons
inactive fast enough. The dialogs are not made to work this way
resulting in tracebacks. Instead of fixing the dialogs we need
to make sure this won't happen, because having more dialogs
open at the same time makes no sense.

This is the least invasive fix for this race condition that
I could come up with.
---
 iw/partition_gui.py |   68 ++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 62 insertions(+), 6 deletions(-)

diff --git a/iw/partition_gui.py b/iw/partition_gui.py
index 8a0739e..f5c7178 100644
--- a/iw/partition_gui.py
+++ b/iw/partition_gui.py
@@ -1313,6 +1313,7 @@ class PartitionWindow(InstallWindow):
             we will want to support creation and removal of partitionable
             devices. This will need some work when that time comes.
         """
+
         device = self.tree.getCurrentDevice()
         if device.partitioned:
             if doClearPartitionedDevice(self.intf,
@@ -1331,6 +1332,16 @@ class PartitionWindow(InstallWindow):
 
             self.refresh(justRedraw=justRedraw)
 
+    def _deleteCB(self, widget):
+        """ deleteCB wrapper
+
+        Blocks and unblocks handlers for the other buttons """
+
+        self._blockButtonHandlers("delete")
+        gui.processEvents()
+        self.deleteCB(widget)
+        self._unblockButtonHandlers("delete")
+
     def createCB(self, *args):
         # First we must decide what parts of the create_storage_dialog
         # we will activate.
@@ -1555,6 +1566,16 @@ class PartitionWindow(InstallWindow):
             self.editPartition(device, isNew = True)
             return
 
+    def _createCB(self, *args):
+        """ createCB wrapper
+
+        Blocks and unblocks handlers for the other buttons """
+
+        self._blockButtonHandlers("create")
+        gui.processEvents()
+        self.createCB(*args)
+        self._unblockButtonHandlers("create")
+
     def resetCB(self, *args):
         if not confirmResetPartitionState(self.intf):
             return
@@ -1569,6 +1590,16 @@ class PartitionWindow(InstallWindow):
         self.tree.clear()
         self.populate()
 
+    def _resetCB(self, *args):
+        """ resetCB wrapper
+
+        Blocks and unblocks handlers for the other buttons """
+
+        self._blockButtonHandlers("reset")
+        gui.processEvents()
+        self.resetCB(*args)
+        self._unblockButtonHandlers("reset")
+
     def refresh(self, justRedraw=None):
         log.debug("refresh: justRedraw=%s" % justRedraw)
         self.stripeGraph.shutDown()
@@ -1637,6 +1668,16 @@ class PartitionWindow(InstallWindow):
         elif isinstance(device, storage.devices.PartitionDevice):
             self.editPartition(device)
 
+    def _editCB(self, *args):
+        """ editCB wrapper
+
+        Blocks and unblocks handlers for the other buttons """
+
+        self._blockButtonHandlers("edit")
+        gui.processEvents()
+        self.editCB(*args)
+        self._unblockButtonHandlers("edit")
+
     # isNew implies that this request has never been successfully used before
     def editRaidArray(self, raiddev, isNew = False):
         # r_d_g -> raid_dialog_gui
@@ -1814,15 +1855,20 @@ class PartitionWindow(InstallWindow):
         buttonBox.set_spacing(6)
         buttonBox.set_layout(gtk.BUTTONBOX_END)
 
-        ops = ((_("_Create"), self.createCB),
-               (_("_Edit"), self.editCB),
-               (_("_Delete"), self.deleteCB),
-               (_("Re_set"), self.resetCB))
+        ops = ((_("_Create"), self._createCB, "create"),
+               (_("_Edit"), self._editCB, "edit"),
+               (_("_Delete"), self._deleteCB, "delete"),
+               (_("Re_set"), self._resetCB, "reset"))
 
-        for label, cb in ops:
+        self._buttons = {}
+        self._handlers = {}
+
+        for label, cb, ident in ops:
             button = gtk.Button(label)
             buttonBox.add (button)
-            button.connect ("clicked", cb)
+
+            self._buttons[ident] = button
+            self._handlers[ident] = button.connect ("clicked", cb)
 
             # We need these to control their sensitivity.
             if label == _("_Edit"):
@@ -1866,3 +1912,13 @@ class PartitionWindow(InstallWindow):
         MVbox.pack_start(gtk.HSeparator(), False)
 
         return MVbox
+
+    def _blockButtonHandlers(self, pressed):
+        for ident in self._buttons:
+            if ident != pressed:
+                self._buttons[ident].handler_block(self._handlers[ident])
+
+    def _unblockButtonHandlers(self, pressed):
+        for ident in self._buttons:
+            if ident != pressed:
+                self._buttons[ident].handler_unblock(self._handlers[ident])
-- 
1.7.3.2

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/anaconda-devel-list


[Index of Archives]     [Kickstart]     [Fedora Users]     [Fedora Legacy List]     [Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]
  Powered by Linux