Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/rust/parking_lot/src/   (Firefox Browser Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 5 kB image not shown  

Quelle  deadlock.rs

  Sprache: Rust
 

//! \[Experimental\] Deadlock detection
//!
//! This feature is optional and can be enabled via the `deadlock_detection` feature flag.
//!
//! # Example
//!
//! ```
//! #[cfg(feature = "deadlock_detection")]
//! { // only for #[cfg]
//! use std::thread;
//! use std::time::Duration;
//! use parking_lot::deadlock;
//!
//! // Create a background thread which checks for deadlocks every 10s
//! thread::spawn(move || {
//!     loop {
//!         thread::sleep(Duration::from_secs(10));
//!         let deadlocks = deadlock::check_deadlock();
//!         if deadlocks.is_empty() {
//!             continue;
//!         }
//!
//!         println!("{} deadlocks detected", deadlocks.len());
//!         for (i, threads) in deadlocks.iter().enumerate() {
//!             println!("Deadlock #{}", i);
//!             for t in threads {
//!                 println!("Thread Id {:#?}", t.thread_id());
//!                 println!("{:#?}", t.backtrace());
//!             }
//!         }
//!     }
//! });
//! } // only for #[cfg]
//! ```

#[cfg(feature = "deadlock_detection")]
pub use parking_lot_core::deadlock::check_deadlock;
pub(crateuse parking_lot_core::deadlock::{acquire_resource, release_resource};

#[cfg(test)]
#[cfg(feature = "deadlock_detection")]
mod tests {
    use crate::{Mutex, ReentrantMutex, RwLock};
    use std::sync::{Arc, Barrier};
    use std::thread::{self, sleep};
    use std::time::Duration;

    // We need to serialize these tests since deadlock detection uses global state
    static DEADLOCK_DETECTION_LOCK: Mutex<()> = crate::const_mutex(());

    fn check_deadlock() -> bool {
        use parking_lot_core::deadlock::check_deadlock;
        !check_deadlock().is_empty()
    }

    #[test]
    fn test_mutex_deadlock() {
        let _guard = DEADLOCK_DETECTION_LOCK.lock();

        let m1: Arc<Mutex<()>> = Default::default();
        let m2: Arc<Mutex<()>> = Default::default();
        let m3: Arc<Mutex<()>> = Default::default();
        let b = Arc::new(Barrier::new(4));

        let m1_ = m1.clone();
        let m2_ = m2.clone();
        let m3_ = m3.clone();
        let b1 = b.clone();
        let b2 = b.clone();
        let b3 = b.clone();

        assert!(!check_deadlock());

        let _t1 = thread::spawn(move || {
            let _g = m1.lock();
            b1.wait();
            let _ = m2_.lock();
        });

        let _t2 = thread::spawn(move || {
            let _g = m2.lock();
            b2.wait();
            let _ = m3_.lock();
        });

        let _t3 = thread::spawn(move || {
            let _g = m3.lock();
            b3.wait();
            let _ = m1_.lock();
        });

        assert!(!check_deadlock());

        b.wait();
        sleep(Duration::from_millis(50));
        assert!(check_deadlock());

        assert!(!check_deadlock());
    }

    #[test]
    fn test_mutex_deadlock_reentrant() {
        let _guard = DEADLOCK_DETECTION_LOCK.lock();

        let m1: Arc<Mutex<()>> = Default::default();

        assert!(!check_deadlock());

        let _t1 = thread::spawn(move || {
            let _g = m1.lock();
            let _ = m1.lock();
        });

        sleep(Duration::from_millis(50));
        assert!(check_deadlock());

        assert!(!check_deadlock());
    }

    #[test]
    fn test_remutex_deadlock() {
        let _guard = DEADLOCK_DETECTION_LOCK.lock();

        let m1: Arc<ReentrantMutex<()>> = Default::default();
        let m2: Arc<ReentrantMutex<()>> = Default::default();
        let m3: Arc<ReentrantMutex<()>> = Default::default();
        let b = Arc::new(Barrier::new(4));

        let m1_ = m1.clone();
        let m2_ = m2.clone();
        let m3_ = m3.clone();
        let b1 = b.clone();
        let b2 = b.clone();
        let b3 = b.clone();

        assert!(!check_deadlock());

        let _t1 = thread::spawn(move || {
            let _g = m1.lock();
            let _g = m1.lock();
            b1.wait();
            let _ = m2_.lock();
        });

        let _t2 = thread::spawn(move || {
            let _g = m2.lock();
            let _g = m2.lock();
            b2.wait();
            let _ = m3_.lock();
        });

        let _t3 = thread::spawn(move || {
            let _g = m3.lock();
            let _g = m3.lock();
            b3.wait();
            let _ = m1_.lock();
        });

        assert!(!check_deadlock());

        b.wait();
        sleep(Duration::from_millis(50));
        assert!(check_deadlock());

        assert!(!check_deadlock());
    }

    #[test]
    fn test_rwlock_deadlock() {
        let _guard = DEADLOCK_DETECTION_LOCK.lock();

        let m1: Arc<RwLock<()>> = Default::default();
        let m2: Arc<RwLock<()>> = Default::default();
        let m3: Arc<RwLock<()>> = Default::default();
        let b = Arc::new(Barrier::new(4));

        let m1_ = m1.clone();
        let m2_ = m2.clone();
        let m3_ = m3.clone();
        let b1 = b.clone();
        let b2 = b.clone();
        let b3 = b.clone();

        assert!(!check_deadlock());

        let _t1 = thread::spawn(move || {
            let _g = m1.read();
            b1.wait();
            let _g = m2_.write();
        });

        let _t2 = thread::spawn(move || {
            let _g = m2.read();
            b2.wait();
            let _g = m3_.write();
        });

        let _t3 = thread::spawn(move || {
            let _g = m3.read();
            b3.wait();
            let _ = m1_.write();
        });

        assert!(!check_deadlock());

        b.wait();
        sleep(Duration::from_millis(50));
        assert!(check_deadlock());

        assert!(!check_deadlock());
    }

    #[cfg(rwlock_deadlock_detection_not_supported)]
    #[test]
    fn test_rwlock_deadlock_reentrant() {
        let _guard = DEADLOCK_DETECTION_LOCK.lock();

        let m1: Arc<RwLock<()>> = Default::default();

        assert!(!check_deadlock());

        let _t1 = thread::spawn(move || {
            let _g = m1.read();
            let _ = m1.write();
        });

        sleep(Duration::from_millis(50));
        assert!(check_deadlock());

        assert!(!check_deadlock());
    }
}

Messung V0.5 in Prozent
C=83 H=85 G=83

¤ Dauer der Verarbeitung: 0.10 Sekunden  (vorverarbeitet am  2026-06-18) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.