Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2007-12-02 11:05:51


Achilleas Margaritis:

> Isn't there a deadlock issue with futures? suppose I have the following
> code:
>
> class A {
> int data;
>
> public:
> int getData() const {
> return data;
> }
>
> void someAction(B *b) {
> future<int> i = bind(b, &B::someAction, this);
> data = i.wait() + 1;
> }
> };
>
> class B {
> int data;
>
> public:
> int someAction(A *a) {
> future<int> j = bind(a, &A::getData);
> return j.wait() + 1;
> }
> };
>
> int main() {
> A *a = new A;
> B *b = new B;
> a->someAction(b);
> }
>
> The above contains a deadlock:

It doesn't, unless the future<int> contains a magic per-object mutex. It
would be a deadlock if A is changed as follows:

class A {
    int data;
    mutable mutex mx;

public:
    int getData() const {
        scoped_lock lock( mx );
        return data;
    }

    void someAction(B *b) {
        scoped_lock lock( mx );
        future<int> i = bind(b, &B::someAction, this);
        data = i.wait() + 1;
    }
};

which is broken. A mutex lock should never encompass a blocking call.

class A {
    int data;
    mutable mutex mx;

public:
    int getData() const {
        scoped_lock lock( mx );
        return data;
    }

    void setData( int v )
    {
        scoped_lock lock( mx );
        data = v;
    }

    void someAction(B *b) {
        future<int> i = bind(b, &B::someAction, this);
        setData( i.wait() + 1 );
    }
};


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk