[PATCH] osmo-gsm-tester[master]: fix: handle dbus signals outside of the glib main loop

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Neels Hofmeyr gerrit-no-reply at lists.osmocom.org
Fri May 5 16:39:16 UTC 2017


Review at  https://gerrit.osmocom.org/2486

fix: handle dbus signals outside of the glib main loop

Collect incoming signals in a defer queue and handle them once the DBus polling
is through.

Related: OS#2220

Change-Id: Ic7520f2165888a4ee0f83b779cd58d20c4e45fa0
---
M src/osmo_gsm_tester/ofono_client.py
1 file changed, 29 insertions(+), 13 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmo-gsm-tester refs/changes/86/2486/1

diff --git a/src/osmo_gsm_tester/ofono_client.py b/src/osmo_gsm_tester/ofono_client.py
index 9a018e1..c3ccda3 100644
--- a/src/osmo_gsm_tester/ofono_client.py
+++ b/src/osmo_gsm_tester/ofono_client.py
@@ -32,10 +32,37 @@
 I_NETREG = 'org.ofono.NetworkRegistration'
 I_SMS = 'org.ofono.MessageManager'
 
+class DeferredHandling:
+    defer_queue = []
+
+    def __init__(self, dbus_iface, handler):
+        self.handler = handler
+        dbus_iface.connect(self.receive_signal)
+
+    def receive_signal(self, *args, **kwargs):
+        DeferredHandling.defer_queue.append((self.handler, args, kwargs))
+
+    @staticmethod
+    def handle_queue():
+        while DeferredHandling.defer_queue:
+            handler, args, kwargs = DeferredHandling.defer_queue.pop(0)
+            handler(*args, **kwargs)
+
+def dbus_connect(dbus_iface, handler):
+    '''This function shall be used instead of directly connecting DBus signals.
+    It ensures that we don't nest a glib main loop within another, and also
+    that we receive exceptions raised within the signal handlers. This makes it
+    so that a signal handler is invoked only after the DBus polling is through
+    by enlisting signals that should be handled in the
+    DeferredHandling.defer_queue.'''
+    DeferredHandling(dbus_iface, handler)
+
+
 def poll():
     global glib_main_ctx
     while glib_main_ctx.pending():
         glib_main_ctx.iteration()
+    DeferredHandling.handle_queue()
 
 def systembus_get(path):
     global bus
@@ -101,7 +128,7 @@
         if self._dbus_obj is not None:
             return self._dbus_obj
         self._dbus_obj = systembus_get(self.path)
-        self._dbus_obj.PropertyChanged.connect(self._on_property_change)
+        dbus_connect(self._dbus_obj.PropertyChanged, self._on_property_change)
         self._on_interfaces_change(self.properties().get('Interfaces'))
         return self._dbus_obj
 
@@ -127,18 +154,7 @@
     def _on_interface_enabled(self, interface_name):
         self.dbg('Interface enabled:', interface_name)
         if interface_name == I_SMS:
-            retries = 3
-            while True:
-                try:
-                    self.dbus_obj()[I_SMS].IncomingMessage.connect(self._on_incoming_message)
-                    break
-                except:
-                    self.dbg('Interface not yet available:', I_SMS)
-                    retries -= 1
-                    time.sleep(1)
-                    if retries <= 0:
-                        self.err('Interface enabled by signal, but not available:', I_SMS)
-                        raise
+            dbus_connect(self.dbus_obj()[I_SMS].IncomingMessage, self._on_incoming_message)
 
     def _on_interface_disabled(self, interface_name):
         self.dbg('Interface disabled:', interface_name)

-- 
To view, visit https://gerrit.osmocom.org/2486
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic7520f2165888a4ee0f83b779cd58d20c4e45fa0
Gerrit-PatchSet: 1
Gerrit-Project: osmo-gsm-tester
Gerrit-Branch: master
Gerrit-Owner: Neels Hofmeyr <nhofmeyr at sysmocom.de>



More information about the gerrit-log mailing list