[node-patches] Change in ovirt-node[master]: ui: Add UIThreadConnection

fabiand at fedoraproject.org fabiand at fedoraproject.org
Wed Mar 13 16:08:19 UTC 2013


Fabian Deutsch has uploaded a new change for review.

Change subject: ui: Add UIThreadConnection
......................................................................

ui: Add UIThreadConnection

This class can be used by other threads to interact/modify the UI
through the UI thread's mainloop.
If the interaction with the UI is not done through such a mechanism,
race conditions will (sooner or later) occur and can lead to all sorts
of UI errors (e.g. inconsitencies, incorrect rendering, ...).

Change-Id: Iee2aec64030919005ab5c849925766700cd91128
Signed-off-by: Fabian Deutsch <fabiand at fedoraproject.org>
---
M scripts/tui/src/ovirt/node/ui/__init__.py
M scripts/tui/src/ovirt/node/ui/urwid_builder.py
M scripts/tui/src/ovirt/node/utils/storage.py
3 files changed, 87 insertions(+), 1 deletion(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-node refs/changes/17/13017/1

diff --git a/scripts/tui/src/ovirt/node/ui/__init__.py b/scripts/tui/src/ovirt/node/ui/__init__.py
index b9a19ac..863042f 100644
--- a/scripts/tui/src/ovirt/node/ui/__init__.py
+++ b/scripts/tui/src/ovirt/node/ui/__init__.py
@@ -595,6 +595,56 @@
         """
         raise NotImplementedError
 
+    def run(self):
+        """Starts the UI
+        """
+        raise NotImplementedError
+
+    def thread_connection(self):
+        """Run a callback in the context of the UI thread
+
+        Returns:
+            A new UIThreadConnection instance
+        """
+        raise NotImplementedError
+
+    class UIThreadConnection(base.Base):
+        """A class to interact with the UI thread
+        This is needed if other threads want to interact with the UI
+        """
+
+        def call(self, callback):
+            """Call a callback in the context of the UI thread
+            This needs to be used when updates to the ui are made
+
+            Args:
+                callback: A callable to be called in the ctx of the ui thread
+
+            Returns:
+                Nothing
+            """
+            raise NotImplementedError
+
+        def close(self):
+            """Close the connection to the UI thread
+            This might be used by the implementation to remove callbacks
+            which handle the communication with this class"
+
+            Returns:
+                Nothing
+            """
+            raise NotImplementedError
+
+        def __del__(self):
+            self.close()
+            super(Window.UIThreadConnection, self).__del__()
+
+        def __enter__(self):
+            return self
+
+        def __exit__(self, exc_type, exc_value, traceback):
+            self.close()
+
     class Navigation(base.Base):
         """A convenience class to navigate through a window
         """
diff --git a/scripts/tui/src/ovirt/node/ui/urwid_builder.py b/scripts/tui/src/ovirt/node/ui/urwid_builder.py
index 2d6ad54..0b0d7a2 100644
--- a/scripts/tui/src/ovirt/node/ui/urwid_builder.py
+++ b/scripts/tui/src/ovirt/node/ui/urwid_builder.py
@@ -20,6 +20,7 @@
 # also available at http://www.gnu.org/copyleft/gpl.html.
 from ovirt.node import ui, exceptions, base
 from ovirt.node.ui import widgets as uw
+import os
 import urwid
 
 """
@@ -458,6 +459,42 @@
 
         self.__loop.run()
 
+    def thread_connection(self):
+        ui_loop = self.__loop
+
+        class UrwidUIThreadConnection(ui.Window.UIThreadConnection):
+            _keep_alive = True
+            _callback = lambda d: 0
+
+            def __init__(self):
+                super(UrwidUIThreadConnection, self).__init__()
+
+                def run_cb(data=None, user_data=None):
+                    self.logger.debug("Calling: %s" % self._callback)
+                    self._callback()
+                    return self._keep_alive
+
+                self.fd = ui_loop.watch_pipe(run_cb)
+
+            def close(self):
+                """Close the connection to the UI thread
+                """
+                self._keep_alive = True
+
+                def close_connection():
+                    self.logger.debug("Connection to UI thread finally closed")
+
+                self.call(close_connection)
+                self.logger.debug("Closing connection to UI thread")
+
+            def call(self, callback):
+                """Run the callback in the context of the UI thread
+                """
+                self._callback = callback
+                os.write(self.fd, "There was a change")
+
+        return UrwidUIThreadConnection()
+
     def suspended(self):
         """Supspends the screen to do something in the foreground
         """
diff --git a/scripts/tui/src/ovirt/node/utils/storage.py b/scripts/tui/src/ovirt/node/utils/storage.py
index 77eb4a6..45f480a 100644
--- a/scripts/tui/src/ovirt/node/utils/storage.py
+++ b/scripts/tui/src/ovirt/node/utils/storage.py
@@ -22,7 +22,6 @@
 from ovirt.node import base
 import os
 
-
 class iSCSI(base.Base):
     """A class to deal with some external iSCSI related functionality
     """


--
To view, visit http://gerrit.ovirt.org/13017
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Iee2aec64030919005ab5c849925766700cd91128
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-node
Gerrit-Branch: master
Gerrit-Owner: Fabian Deutsch <fabiand at fedoraproject.org>



More information about the node-patches mailing list