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)"
|
||||
|
||||
# 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
|
||||
|
||||
if (x is None) and (y is None) and (desc is None) and (job_id is None) and (job_date is None):
|
||||
# Empty initialization - will be filled later
|
||||
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
|
||||
|
||||
# Set metadata if provided
|
||||
if desc is not None:
|
||||
self.description = desc
|
||||
if job_id is not None:
|
||||
self.job_id = job_id
|
||||
if job_date is not None:
|
||||
self.job_date = job_date
|
||||
|
||||
else:
|
||||
raise ValueError("Wrong usage of __init__!")
|
||||
|
||||
def get_number_of_channels(self):
|
||||
"""Returns 1 for temperature data."""
|
||||
|
||||
@@ -998,8 +998,14 @@ class DamarisGUI:
|
||||
"""
|
||||
# Check if temperature monitoring is enabled
|
||||
if not config.get("enable_temperature_monitoring", False):
|
||||
# Stop any existing monitor if temperature monitoring is disabled
|
||||
self.stop_temperature_monitoring()
|
||||
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")
|
||||
temp_interval = config.get("temperature_interval", 2.0)
|
||||
|
||||
|
||||
@@ -10,6 +10,14 @@ import threading
|
||||
import time
|
||||
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.tools.temperature import TemperatureController
|
||||
|
||||
@@ -89,10 +97,42 @@ class TemperatureMonitor(threading.Thread):
|
||||
self.result.job_date = datetime.datetime.now()
|
||||
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:
|
||||
# Make a deep copy of the result to avoid thread issues
|
||||
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:
|
||||
print(f"TemperatureMonitor error: {e}")
|
||||
@@ -112,8 +152,14 @@ class TemperatureMonitor(threading.Thread):
|
||||
"""
|
||||
self._running = False
|
||||
self.quit_flag.set()
|
||||
# Wait for the thread to finish its current iteration
|
||||
self.join(timeout=self.interval + 0.5)
|
||||
# Wait for the thread to finish, with a generous timeout
|
||||
# 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):
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user