mirror of
https://github.com/emilk/egui.git
synced 2026-08-29 12:50:04 -04:00
Fix deadlock in ImageLoader, FileLoader, EhttpLoader (#7494)
* Recently CI runs started to hang randomly: https://github.com/emilk/egui/actions/runs/17427449210/job/49477714447?pr=7359 This fixes the deadlock and adds the basic deadlock detection we also added to Mutexes in #7468. Also, interestingly, the more sophisticated deadlock detection (behind the deadlock_detection feature) didn't catch this for some reason. I wonder why it exists in the first place, when parking_lot also has built in deadlock detection? It also seems to make tests slower, widget_tests usually needs ~30s, with the deadlock detection removed its only ~12s.
This commit is contained in:
@@ -2,8 +2,13 @@
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#[cfg(not(feature = "deadlock_detection"))]
|
||||
const DEADLOCK_DURATION: std::time::Duration = std::time::Duration::from_secs(30);
|
||||
|
||||
#[cfg(not(feature = "deadlock_detection"))]
|
||||
mod mutex_impl {
|
||||
use super::DEADLOCK_DURATION;
|
||||
|
||||
/// Provides interior mutability.
|
||||
///
|
||||
/// This is a thin wrapper around [`parking_lot::Mutex`], except if
|
||||
@@ -25,7 +30,7 @@ mod mutex_impl {
|
||||
pub fn lock(&self) -> MutexGuard<'_, T> {
|
||||
if cfg!(debug_assertions) {
|
||||
self.0
|
||||
.try_lock_for(std::time::Duration::from_secs(30))
|
||||
.try_lock_for(DEADLOCK_DURATION)
|
||||
.expect("Looks like a deadlock!")
|
||||
} else {
|
||||
self.0.lock()
|
||||
@@ -127,6 +132,8 @@ mod mutex_impl {
|
||||
|
||||
#[cfg(not(feature = "deadlock_detection"))]
|
||||
mod rw_lock_impl {
|
||||
use super::DEADLOCK_DURATION;
|
||||
|
||||
/// The lock you get from [`RwLock::read`].
|
||||
pub use parking_lot::MappedRwLockReadGuard as RwLockReadGuard;
|
||||
|
||||
@@ -151,12 +158,26 @@ mod rw_lock_impl {
|
||||
impl<T: ?Sized> RwLock<T> {
|
||||
#[inline(always)]
|
||||
pub fn read(&self) -> RwLockReadGuard<'_, T> {
|
||||
parking_lot::RwLockReadGuard::map(self.0.read(), |v| v)
|
||||
let guard = if cfg!(debug_assertions) {
|
||||
self.0
|
||||
.try_read_for(DEADLOCK_DURATION)
|
||||
.expect("Looks like a deadlock!")
|
||||
} else {
|
||||
self.0.read()
|
||||
};
|
||||
parking_lot::RwLockReadGuard::map(guard, |v| v)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn write(&self) -> RwLockWriteGuard<'_, T> {
|
||||
parking_lot::RwLockWriteGuard::map(self.0.write(), |v| v)
|
||||
let guard = if cfg!(debug_assertions) {
|
||||
self.0
|
||||
.try_write_for(DEADLOCK_DURATION)
|
||||
.expect("Looks like a deadlock!")
|
||||
} else {
|
||||
self.0.write()
|
||||
};
|
||||
parking_lot::RwLockWriteGuard::map(guard, |v| v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user