From 507a635e1667bc69809eb94f7de29109548d126b Mon Sep 17 00:00:00 2001
From: Jan David Mol <mol@astron.nl>
Date: Tue, 26 Mar 2024 10:58:48 +0100
Subject: [PATCH] Fix race conditions

---
 .../devices/base_device_classes/lofar_device.py    | 14 +++++++++-----
 .../devices/base_device_classes/opcua_device.py    |  3 ++-
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/tangostationcontrol/tangostationcontrol/devices/base_device_classes/lofar_device.py b/tangostationcontrol/tangostationcontrol/devices/base_device_classes/lofar_device.py
index c0e267eef..4d3d1e812 100644
--- a/tangostationcontrol/tangostationcontrol/devices/base_device_classes/lofar_device.py
+++ b/tangostationcontrol/tangostationcontrol/devices/base_device_classes/lofar_device.py
@@ -16,7 +16,7 @@ from pathlib import Path
 
 from typing import List, Dict, Tuple
 from functools import partial
-from inspect import iscoroutinefunction
+from inspect import isawaitable
 
 import numpy
 from attribute_wrapper.attribute_wrapper import AttributeWrapper
@@ -784,10 +784,12 @@ class LOFARDevice(Device):
 
         func = self._read_attribute(attr_name)
 
-        if iscoroutinefunction(func):
+        if isawaitable(func):
             return asyncio.run(func())
         else:
-            return func()
+            result = func()
+
+            return asyncio.run(result) if isawaitable(result) else result
 
     async def async_read_attribute(self, attr_name):
         """Read the value of a certain attribute (directly from the hardware).
@@ -797,10 +799,12 @@ class LOFARDevice(Device):
 
         func = self._read_attribute(attr_name)
 
-        if iscoroutinefunction(func):
+        if isawaitable(func):
             return await func()
         else:
-            return func()
+            result = func()
+
+            return await result if isawaitable(result) else result
 
     def wait_attribute(self, attr_name, value, timeout=10, pollperiod=0.2):
         """Wait until the given attribute obtains the given value.
diff --git a/tangostationcontrol/tangostationcontrol/devices/base_device_classes/opcua_device.py b/tangostationcontrol/tangostationcontrol/devices/base_device_classes/opcua_device.py
index 30469301a..eb903b5c8 100644
--- a/tangostationcontrol/tangostationcontrol/devices/base_device_classes/opcua_device.py
+++ b/tangostationcontrol/tangostationcontrol/devices/base_device_classes/opcua_device.py
@@ -173,7 +173,8 @@ class OPCUADevice(LOFARDevice):
             self.OPC_Time_Out,
             self.Fault,
             self.opcua_connection_status,
-            event_loop=self.event_loop_thread.event_loop,
+            # TODO(JDM): This results in a deadlock when polling attributes and mixing green/non-green functionality
+            # event_loop=self.event_loop_thread.event_loop,
             device=self,
         )
         self.opcua_connection.node_path_prefix = self.OPC_Node_Path_Prefix
-- 
GitLab