I'm working on a project that will have a number of different threads that all need to access the same structure. One thread will update the contents of the structure based on data read from sensors, while the other threads read the contents (for publishing to various services at various rates), so I am using a mutex.
Currently I have just two threads, a producer that populates the structure, and a consumer that reads the contents of the structure.
The thread that reads the structure looks like this:
let guard = data_mutex.lock().unwrap();
let sensor_hub_data = *guard;
log::info!(
"ALS: {}, White: {}, Lux: {}",
sensor_hub_data.veml.raw_als,
sensor_hub_data.veml.raw_white,
sensor_hub_data.veml.lux,
);
The thread that populates the structure does so by doing the following.
let mut locked_mutex = data_mutex.lock().unwrap();
// Copy over the most recently send data from the channel into the structure.
match received_data {
SensorData::Bsec { data } => (*locked_mutex).bsec = data,
SensorData::Veml { data } => (*locked_mutex).veml = data,
}
As expected, the reader thread prints out fluctuating sensor data, somewhat like so:
I (618775) environment_monitor_rust: ALS: 0, White: 0, Lux: 0.0
I (628775) environment_monitor_rust: ALS: 91, White: 163, Lux: 5.2416
I (632935) environment_monitor_rust: ALS: 90, White: 162, Lux: 5.184
I (635005) environment_monitor_rust: ALS: 91, White: 162, Lux: 5.2416
To try to make the match statement tidier, I moved the dereference to be part of the variable above it, like so:
let mut locked_mutex = *data_mutex.lock().unwrap();
// Copy over the most recently send data from the channel into the structure.
match received_data {
SensorData::Bsec { data } => locked_mutex.bsec = data,
SensorData::Veml { data } => locked_mutex.veml = data,
}
When I changed it to be like this, the thread that reads the structure no longer seems to be seeing updated data. It's output looks now looks like this:
I (618775) environment_monitor_rust: ALS: 0, White: 0, Lux: 0.0
I (628775) environment_monitor_rust: ALS: 0, White: 0, Lux: 0.0
I (632935) environment_monitor_rust: ALS: 0, White: 0, Lux: 0.0
I (635005) environment_monitor_rust: ALS: 0, White: 0, Lux: 0.0
Why does moving the de-referencing in the producer outside of the match expression cause the structure to no longer be updated?