Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Select Features and Configuration

Deloxide’s features are Cargo compile-time choices, not runtime switches. Start with the default active wait-for detector, then add only the evidence or test behavior needed for the environment. The public base API is always Deloxide, Mutex, RwLock, Condvar, DeadlockInfo, and thread.

BuildAdditional API enabledRuntime work addedIntended environmentComplete Cargo.toml dependency
DefaultBase API onlyActive wait-for tracking for supported, tracked primitives; callbacks on findings.Reproductions and measured normal deployments.deloxide = "1.1.0"
logging-and-visualizationDeloxide::with_log, no_logging, showcase, and showcase_this.Event queue, serialization, asynchronous log writer, and file I/O.Incident capture and local investigation.deloxide = { version = "1.1.0", features = ["logging-and-visualization"] }
lock-order-graphwith_lock_order_checking and no_lock_order_checking.Historical lock-order edges and cycle checks in addition to active tracking.Development and CI.deloxide = { version = "1.1.0", features = ["lock-order-graph"] }
stress-testStressConfig, StressMode, with_random_stress, with_component_stress, and with_stress_config.Configured delays/preemption behavior around lock attempts; slower, less deterministic execution.Focused tests and reproductions only.deloxide = { version = "1.1.0", features = ["stress-test"] }
All optional featuresAll APIs above.Logging, historical order tracking, and optional stress behavior when selected by the builder.Comprehensive local/CI diagnosis, after measuring the combined cost.deloxide = { version = "1.1.0", features = ["logging-and-visualization", "lock-order-graph", "stress-test"] }

Use one dependency line in the application’s Cargo.toml; the cells above are complete alternatives, not lines to combine.

Builder defaults follow compiled features

Deloxide::new always supplies a callback that panics with the report unless you replace it with callback. When logging-and-visualization is compiled, it enables logging by default with the path deloxide.log; change that path with with_log, or disable logging for the initial configuration with no_logging. When lock-order-graph is compiled, lock-order checking is enabled by default; make the initial policy explicit with with_lock_order_checking, or use no_lock_order_checking for a controlled baseline. Stress compilation alone does not add delays: select random or component stress with its corresponding builder method.

#![allow(unused)]
fn main() {
extern crate deloxide;
#[cfg(feature = "logging-and-visualization")]
{
    use deloxide::Deloxide;

    Deloxide::new()
        .with_log("logs/deloxide_{timestamp}.log")
        .callback(|report| eprintln!("{report:?}"))
        .start()
        .expect("logging detector initialization");
}
#[cfg(not(feature = "logging-and-visualization"))]
{
    let _ = "this configuration needs the logging-and-visualization feature";
}
}
#![allow(unused)]
fn main() {
extern crate deloxide;
#[cfg(feature = "lock-order-graph")]
{
    use deloxide::{DeadlockSource, Deloxide};

    Deloxide::new()
        .with_lock_order_checking()
        .callback(|report| match report.source {
            DeadlockSource::WaitForGraph => eprintln!("active cycle"),
            DeadlockSource::LockOrderViolation => eprintln!("potential order cycle"),
        })
        .start()
        .expect("order-checking detector initialization");
}
#[cfg(not(feature = "lock-order-graph"))]
{
    let _ = "this configuration needs the lock-order-graph feature";
}
}

Both builder calls are feature-gated at compile time. Do not put them behind only a runtime if: a binary built without the feature has no such methods.

Choose the evidence level deliberately

The lock-order-graph feature can report DeadlockSource::LockOrderViolation when observed acquisitions close a historical order cycle. It is useful early in development, but it is not evidence that threads are blocked now. The base wait-for detector’s DeadlockSource::WaitForGraph is the active, validated-cycle finding. Keep those response paths distinct even when all features are compiled.

Stress mode changes scheduling to make a suspected bug easier to reproduce; it does not turn a potential order warning into a confirmed deadlock. Logging adds history for the supported events it receives, not a complete trace of every thread and primitive in the process. See Choosing a Mode for operational trade-offs, Finding Inconsistent Lock Order for potential findings, and Stress Test a Suspected Race for test-only stress workflows.

Cargo features are fixed when the application is built. Choose one runtime builder configuration and start it before instrumented work. Repeated start() calls are accepted, but their effects are asymmetric: the first successfully installed callback and global logger win; an enabled lock-order graph is created or replaced, while a later disabled setting does not remove an existing graph; and stress mode/configuration is overwritten on each start. Existing ownership and wait state is not reset coherently with those changes. Repeated starts are therefore partial, unsupported reconfiguration, not a reliable reset or toggle. Use separate processes for clean configurations; see Manage Lifecycle and Callbacks for the exact behavior.