Public Access
fix thread locking when reading temeprature
This commit is contained in:
@@ -33,23 +33,17 @@ class TemperatureResult(Resultable, Drawable):
|
|||||||
self.ylabel = "Temperature (C)"
|
self.ylabel = "Temperature (C)"
|
||||||
|
|
||||||
# Initialize data lists
|
# Initialize data lists
|
||||||
|
self.x = [] if x is None else x
|
||||||
|
self.y = [] if y is None else y
|
||||||
self.setpoint = [] if setpoint is None else setpoint
|
self.setpoint = [] if setpoint is None else setpoint
|
||||||
|
|
||||||
if (x is None) and (y is None) and (desc is None) and (job_id is None) and (job_date is None):
|
# Set metadata if provided
|
||||||
# Empty initialization - will be filled later
|
if desc is not None:
|
||||||
self.x = []
|
|
||||||
self.y = []
|
|
||||||
|
|
||||||
elif (x is not None) and (y is not None) and (desc is not None) and (job_id is not None) and (job_date is not None):
|
|
||||||
# Full initialization
|
|
||||||
self.x = x
|
|
||||||
self.y = y
|
|
||||||
self.description = desc
|
self.description = desc
|
||||||
|
if job_id is not None:
|
||||||
self.job_id = job_id
|
self.job_id = job_id
|
||||||
|
if job_date is not None:
|
||||||
self.job_date = job_date
|
self.job_date = job_date
|
||||||
|
|
||||||
else:
|
|
||||||
raise ValueError("Wrong usage of __init__!")
|
|
||||||
|
|
||||||
def get_number_of_channels(self):
|
def get_number_of_channels(self):
|
||||||
"""Returns 1 for temperature data."""
|
"""Returns 1 for temperature data."""
|
||||||
|
|||||||
@@ -998,8 +998,14 @@ class DamarisGUI:
|
|||||||
"""
|
"""
|
||||||
# Check if temperature monitoring is enabled
|
# Check if temperature monitoring is enabled
|
||||||
if not config.get("enable_temperature_monitoring", False):
|
if not config.get("enable_temperature_monitoring", False):
|
||||||
|
# Stop any existing monitor if temperature monitoring is disabled
|
||||||
|
self.stop_temperature_monitoring()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Stop any existing monitor before starting a new one
|
||||||
|
if self.temp_monitor is not None:
|
||||||
|
self.stop_temperature_monitoring()
|
||||||
|
|
||||||
controller_type = config.get("temperature_controller_type", "eurotherm")
|
controller_type = config.get("temperature_controller_type", "eurotherm")
|
||||||
temp_interval = config.get("temperature_interval", 2.0)
|
temp_interval = config.get("temperature_interval", 2.0)
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,14 @@ import threading
|
|||||||
import time
|
import time
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
|
try:
|
||||||
|
import gi
|
||||||
|
gi.require_version('Gdk', '3.0')
|
||||||
|
from gi.repository import Gdk as gdk
|
||||||
|
HAS_GTK = True
|
||||||
|
except (ImportError, ValueError):
|
||||||
|
HAS_GTK = False
|
||||||
|
|
||||||
from damaris.data import TemperatureResult
|
from damaris.data import TemperatureResult
|
||||||
from damaris.tools.temperature import TemperatureController
|
from damaris.tools.temperature import TemperatureController
|
||||||
|
|
||||||
@@ -89,10 +97,42 @@ class TemperatureMonitor(threading.Thread):
|
|||||||
self.result.job_date = datetime.datetime.now()
|
self.result.job_date = datetime.datetime.now()
|
||||||
self.result.job_id = id(self)
|
self.result.job_id = id(self)
|
||||||
|
|
||||||
# Optional: store in data_pool
|
# Optional: store in data_pool (thread-safe for GTK)
|
||||||
if self.data_pool is not None:
|
if self.data_pool is not None:
|
||||||
|
# Make a deep copy of the result to avoid thread issues
|
||||||
with self._lock:
|
with self._lock:
|
||||||
self.data_pool[self.data_key] = self.result
|
# Copy the data lists
|
||||||
|
x_copy = self.result.x[:] if hasattr(self.result, 'x') and self.result.x else []
|
||||||
|
y_copy = self.result.y[:] if hasattr(self.result, 'y') and self.result.y else []
|
||||||
|
setpoint_copy = self.result.setpoint[:] if hasattr(self.result, 'setpoint') and self.result.setpoint else []
|
||||||
|
job_id_copy = getattr(self.result, 'job_id', None)
|
||||||
|
job_date_copy = getattr(self.result, 'job_date', None)
|
||||||
|
desc_copy = getattr(self.result, 'description', {}).copy() if hasattr(self.result, 'description') and isinstance(getattr(self.result, 'description', None), dict) else {}
|
||||||
|
xlabel_copy = getattr(self.result, 'xlabel', "Time (s)")
|
||||||
|
ylabel_copy = getattr(self.result, 'ylabel', "Temperature (C)")
|
||||||
|
|
||||||
|
# Create copy outside the lock to minimize lock time
|
||||||
|
result_copy = TemperatureResult(
|
||||||
|
x=x_copy,
|
||||||
|
y=y_copy,
|
||||||
|
setpoint=setpoint_copy,
|
||||||
|
desc=desc_copy,
|
||||||
|
job_id=job_id_copy,
|
||||||
|
job_date=job_date_copy
|
||||||
|
)
|
||||||
|
result_copy.xlabel = xlabel_copy
|
||||||
|
result_copy.ylabel = ylabel_copy
|
||||||
|
|
||||||
|
# Update data_pool in GTK thread if GTK is available
|
||||||
|
if HAS_GTK:
|
||||||
|
# Use gdk.threads_enter/leave for thread-safe GTK access
|
||||||
|
gdk.threads_enter()
|
||||||
|
try:
|
||||||
|
self.data_pool[self.data_key] = result_copy
|
||||||
|
finally:
|
||||||
|
gdk.threads_leave()
|
||||||
|
else:
|
||||||
|
self.data_pool[self.data_key] = result_copy
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"TemperatureMonitor error: {e}")
|
print(f"TemperatureMonitor error: {e}")
|
||||||
@@ -112,8 +152,14 @@ class TemperatureMonitor(threading.Thread):
|
|||||||
"""
|
"""
|
||||||
self._running = False
|
self._running = False
|
||||||
self.quit_flag.set()
|
self.quit_flag.set()
|
||||||
# Wait for the thread to finish its current iteration
|
# Wait for the thread to finish, with a generous timeout
|
||||||
self.join(timeout=self.interval + 0.5)
|
# Use a longer timeout to account for potential delays
|
||||||
|
if self.is_alive():
|
||||||
|
self.join(timeout=5.0) # Wait up to 5 seconds
|
||||||
|
if self.is_alive():
|
||||||
|
print("Warning: TemperatureMonitor thread did not stop gracefully")
|
||||||
|
# Thread is still running, but we can't force stop it
|
||||||
|
# The next start will check if it's alive and handle it
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user