Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detecting deadlock with single qutex/qrwlock #1

Open
yjh0502 opened this issue Apr 1, 2018 · 1 comment
Open

Detecting deadlock with single qutex/qrwlock #1

yjh0502 opened this issue Apr 1, 2018 · 1 comment

Comments

@yjh0502
Copy link

yjh0502 commented Apr 1, 2018

Here's example code which causes deadlock without unsafe code.

extern crate futures;
extern crate qutex;

use qutex::*;
use futures::prelude::*;

fn main() {
    let lock = QrwLock::from(0i32);

    let f = lock.clone().write().and_then(move |mut guard_w| {
        eprintln!("write lock acquired");
        lock.read().and_then(move |guard_r| {
            eprintln!("read lock acquired");

            let r0 = *guard_r;
            *guard_w += 1;
            let r1 = *guard_r;
            assert_eq!(r0, r1);
            Ok(())
        })
    });

    assert_eq!(Ok(()), f.wait());
}

Is there any way to detect the deadlock? It would be nice for FutureGuard to return Deadlocked error (just like Canceled error) if there's any prior FutureGuard which belongs to current task. In that case, above example will return Error(Deadlocked) on f.wait() instead of hanging on deadlock.

@c0gent
Copy link
Member

c0gent commented Apr 2, 2018

As someone who has struggled plenty with deadlocks, I have often considered ways of implementing some sort of detection system. It wouldn't be too hard to add a feature-gated system to detect deadlocks caused by other Qutex/QrwLocks (as in your example) and I would be completely open to adding one. Most deadlocks, however, come from interactions with other, outside, queues and scheduling systems (threads and event loops). Developing a system to detect deadlocks caused by interactions with those systems would be quite an undertaking.

What I often do in my applications is to use a dependency graph to plan out ahead of time, in which order things will be enqueued. Here is a simple example of this. Here is a more complicated example which is rebuildable. If implemented correctly, using graphs like this to schedule tasks which require exclusive access to resources (usually a region of memory, aka. a buffer) will prevent deadlocks from happening in the first place.

I'm interested to hear any other ideas you may have as to what else could/should be done and how they could be implemented.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants