Boost logo

Boost Users :

Subject: Re: [Boost-users] [threads] calling unlock twice
From: vicente.botet (vicente.botet_at_[hidden])
Date: 2009-05-27 18:25:55


Hi,

in case you are interested in, Toward Boost.Synchro (https://svn.boost.org/trac/boost/wiki/LibrariesUnderConstruction#Boost.Synchro) provides an unique_arrray_locker class which allows you to lock/unlock several mutex at the same time in a exception-safe fashion.

    boost::synchro::array_unique_locker<boost::mutex, 3> lk(m1, m2, m3, 100);

Please let me know wht do you think?

Regards,
Vicente
----- Original Message -----
From: Ovanes Markarian
To: boost-users_at_[hidden]
Sent: Sunday, May 17, 2009 5:22 PM
Subject: Re: [Boost-users] [threads] calling unlock twice

Sorry some shortcut sent my message before I was able to finish it.

On Sun, May 17, 2009 at 5:12 PM, Ovanes Markarian <om_boost_at_[hidden]> wrote:

Hello *,

I wrote a code which used a RAII idiom to lock multiple mutex instances in ctor and unlock them in dtor.

This resulted in the class similar to:

struct lock_many
{

       lock_many() : //default init members
       {}

    lock_many(mutex& m1, mutex& m2, ...)
       : m1_(m1), ...
    {
       boost::lock(*m1_, *m2_, ...);
    }

    ~lock_many()
    {
        //some asserts here, which ensure that either all mutex pointers are NULL or unequl to each other
        if(m1_==NULL && m2_==NULL && ...)
           return; // all are NULL no unlock needed

        m1_->unlock(), m2_->unlock, ...;
    }

   private:
     mutex* m1_;
     mutex* m2_;
};

Now I used the swap to lock/unlock a member variable:

class
{

  public:

     void lock()
     {
        using namespace std;
        swap(many_locked_, lock_many(m1_, m2_...));
     }

     void unlock()
     {
        using namespace std;
        swap(many_locked_, lock_many());
     }

  private:
    lock_many many_locked_;
};

As I found out, unlock did not unlock, due to std::swap implemenation.

swap has a temporary, which gets the many_locked_ assigned at the end of swap the dtor is called and unlocks the mutexes. Leaving the swap(many_locked_, lock_many()) sentence cause lock_many() temporary to go out of scope and calls unlock again. Now mutexes get lock and my app dead locks. Should that at least be asserted somehow, that calling subsequent unlock is not a good idea?

Ahh, my boost version is 1.36 and I am using MSVC 2008


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net