Простой, воспроизводимый пример проблемы ( детская площадка ):
// create array inside mutex
let mutex = Mutex::new([ 0i32 ]);
// get reference to item inside array
let item: &i32 = mutex.lock().unwrap().get(0).unwrap();
// use reference for something
println!("item = {:?}", item);
mutex.lock().unwrap()
возвращает MutexGuard<'_, Option<i32>>
, который заимствует данные внутри мьютекса. Он также владеет блокировкой данных, которая освобождается при снятии защиты, что означает, что никто не может заимствовать данные одновременно.
Когда вы вызываете метод внутреннего типа для этого предохранителя (например, .get
в приведенном выше примере или .interrupt_evt
в вашем коде), он будет заимствован из времени жизни охранника, поскольку вы можете безопасно получать доступ к данным только при наличии защиты. Но защита не хранится ни в одной переменной, поэтому она существует только временно для этого оператора и сразу же удаляется в конце. Поэтому вы не можете получить ссылку на данные вне оператора.
Решить эту проблему очень просто: сначала сохраните охрану в переменной, а затем позаимствуйте у нее. Это гарантирует, что охранник живет дольше, чем рекомендации, которые вы получаете от него ( детская площадка ):
// create array inside mutex
let mutex = Mutex::new([ 0i32 ]);
// get reference to item inside array
let guard = mutex.lock().unwrap();
let item: &i32 = guard.get(0).unwrap();
// use reference for something
println!("item = {:?}", item);
// guard is now destroyed at end of scope
// and mutex lock is released here