fix: thread lock in tcp send/receive

This commit is contained in:
2026-07-21 14:47:47 +02:00
parent bd5eaa3446
commit a9a49bef89
+37 -22
View File
@@ -3,7 +3,7 @@ use std::{
fmt, fmt,
io::{Read, Write}, io::{Read, Write},
net::{IpAddr, SocketAddr, TcpStream}, net::{IpAddr, SocketAddr, TcpStream},
sync::{Mutex, OnceLock}, sync::{Arc, Mutex, OnceLock},
time::Duration, time::Duration,
}; };
@@ -33,8 +33,7 @@ fn instances() -> &'static Mutex<HashMap<(IpAddr, u8), ()>> {
pub struct DSP408 { pub struct DSP408 {
connection: types::DeviceConnection, connection: types::DeviceConnection,
socket: Option<TcpStream>, socket: Arc<Mutex<Option<TcpStream>>>,
lock: Mutex<()>,
connected: bool, connected: bool,
state: Option<types::DSPState>, state: Option<types::DSPState>,
} }
@@ -62,9 +61,7 @@ impl DSP408 {
device_id, device_id,
}, },
socket: None, socket: Arc::new(Mutex::new(None)),
lock: Mutex::new(()),
connected: false, connected: false,
@@ -72,19 +69,13 @@ impl DSP408 {
}) })
} }
fn send_raw(&mut self, data: &[u8]) -> Result<(), DSPError> { fn send_raw(socket: &mut TcpStream, data: &[u8]) -> Result<(), DSPError> {
let _guard = self.lock.lock().unwrap();
let socket = self.socket.as_mut().ok_or(DSPError::NotConnected)?;
socket.write_all(data)?; socket.write_all(data)?;
Ok(()) Ok(())
} }
fn recv_raw(&mut self) -> Result<Vec<u8>, DSPError> { fn recv_raw(socket: &mut TcpStream) -> Result<Vec<u8>, DSPError> {
let socket = self.socket.as_mut().ok_or(DSPError::NotConnected)?;
let mut buffer = vec![0u8; RECV_BUFSIZE]; let mut buffer = vec![0u8; RECV_BUFSIZE];
match socket.read(&mut buffer) { match socket.read(&mut buffer) {
@@ -101,10 +92,14 @@ impl DSP408 {
} }
} }
pub fn send_recv(&mut self, command: &[u8]) -> Result<types::DeviceResponseType, DSPError> { pub fn send_recv(&self, command: &[u8]) -> Result<types::DeviceResponseType, DSPError> {
self.send_raw(command)?; let mut socket_guard = self.socket.lock().unwrap();
let raw = self.recv_raw()?; let socket = socket_guard.as_mut().ok_or(DSPError::NotConnected)?;
Self::send_raw(socket, command)?;
let raw = Self::recv_raw(socket)?;
let frame = extract_frame(&raw)?; let frame = extract_frame(&raw)?;
@@ -117,6 +112,10 @@ impl DSP408 {
self.connected self.connected
} }
pub fn connection(&self) -> &types::DeviceConnection {
&self.connection
}
pub fn state(&self) -> Result<&types::DSPState, DSPError> { pub fn state(&self) -> Result<&types::DSPState, DSPError> {
self.state.as_ref().ok_or(DSPError::NotConnected) self.state.as_ref().ok_or(DSPError::NotConnected)
} }
@@ -144,16 +143,31 @@ impl DSP408 {
stream.set_read_timeout(Some(SOCKET_TIMEOUT))?; stream.set_read_timeout(Some(SOCKET_TIMEOUT))?;
self.socket = Some(stream); {
let mut socket = self.socket.lock().unwrap();
*socket = Some(stream);
}
let handshake = commands::build_handshake(); let handshake = commands::build_handshake();
self.send_raw(&handshake)?; {
let mut socket = self.socket.lock().unwrap();
let socket = socket.as_mut().ok_or(DSPError::NotConnected)?;
Self::send_raw(socket, &handshake)?;
}
let start = std::time::Instant::now(); let start = std::time::Instant::now();
while start.elapsed() < SOCKET_TIMEOUT { while start.elapsed() < SOCKET_TIMEOUT {
let raw = self.recv_raw()?; let raw = {
let mut socket = self.socket.lock().unwrap();
let socket = socket.as_mut().ok_or(DSPError::NotConnected)?;
Self::recv_raw(socket)?
};
let frame = extract_frame(&raw)?; let frame = extract_frame(&raw)?;
let response = map_response(&frame)?; let response = map_response(&frame)?;
@@ -198,9 +212,10 @@ impl DSP408 {
pub fn disconnect(&mut self) { pub fn disconnect(&mut self) {
let key = (self.connection.host, self.connection.device_id); let key = (self.connection.host, self.connection.device_id);
if let Some(mut socket) = self.socket.take() { let mut socket_guard = self.socket.lock().unwrap();
let _ = socket.write_all(&commands::build_disconnect());
if let Some(mut socket) = socket_guard.take() {
let _ = socket.write_all(&commands::build_disconnect());
let _ = socket.shutdown(std::net::Shutdown::Both); let _ = socket.shutdown(std::net::Shutdown::Both);
} }