Results 1 to 4 of 4

Thread: bug in RWRecMutex

  1. #1
    jlawson71 is offline Registered User
    Name: Jeff Lawson
    Organization: Omniture
    Project: High voulme data transfer
    Join Date
    May 2008
    Posts
    2

    bug in RWRecMutex

    I think I have found a deadlock in RWRecMutex.

    Thread A calls readLock
    Thread B calls writeLock
    Thread A calls readLock

    A co-worker has written a little test application that shows this. He will post it in a moment.

  2. #2
    kalaxy is offline Registered User
    Name: Kalon Mills
    Organization: Omniture, Inc.
    Project: Distributed/Parallel processing.
    Join Date
    Dec 2007
    Location
    California
    Posts
    11
    Code that shows deadlock in action.
    Code:
    #include <IceUtil/RWRecMutex.h>
    #include <IceUtil/Thread.h>
    
    using namespace std;
    
    class Base : public IceUtil::Thread {
    protected:
        IceUtil::RWRecMutex &mut;
    public:
        Base( IceUtil::RWRecMutex &m ) : mut(m) {}
    
    };
    
    class Read : public Base {
    public:
        Read( IceUtil::RWRecMutex &m ) : Base(m) { }
    
        void run() {
            IceUtil::ThreadControl self;
            cout << "Trying to get ReadLock." << endl;
            IceUtil::RWRecMutex::RLock rlock(mut);
            cout << "ReadLock aquired." << endl;
    
            self.sleep(IceUtil::Time::seconds(1));
    
            cout << "Trying to get ReadLock again." << endl;
            IceUtil::RWRecMutex::RLock rlock2(mut);  //Deadlock here.
            cout << "ReadLock aquired again." << endl;
        }
    };
    
    class Write : public Base {
    public:
        Write( IceUtil::RWRecMutex &m ) : Base(m) { }
    
        void run() {
            IceUtil::ThreadControl self;
            cout << "Trying to get WriteLock." << endl;
            IceUtil::RWRecMutex::WLock wlock(mut);
            cout << "WriteLock." << endl;
        }
    };
    
    int main() {
        cout << "Starting." << endl;
        IceUtil::RWRecMutex mut;
        IceUtil::ThreadPtr r = new Read(mut);
        IceUtil::ThreadPtr w = new Write(mut);
    
        IceUtil::ThreadControl rtc, wtc;
    
        rtc = r->start();
        wtc = w->start();
    
        rtc.join();
        wtc.join();
    
        cout << "Finished." << endl;
        return 0;
    }
    Under Linux using gcc.
    Last edited by kalaxy; 10-16-2009 at 05:25 PM. Reason: Added compiler and OS info

  3. #3
    michi's Avatar
    michi is offline Registered User
    Name: Michi Henning
    Organization: Triodia Technologies
    Project: I have a passing interest in Ice :-)
    Join Date
    Feb 2003
    Location
    Brisbane, Australia
    Posts
    1,055
    Thanks for the report!

    I can reproduce the problem here. The cause is that, while there is a waiting writer, readers are unconditionally blocked when they try to acquire a read lock:

    Code:
    void
    IceUtil::RWRecMutex::readLock() const
    {
        Mutex::Lock lock(_mutex);
    
        //
        // Wait while a writer holds the lock or while writers or an upgrader
        // are waiting to get the lock.
        //
        while(_count < 0 || _waitingWriters != 0)
        {
            _readers.wait(lock);
        }
        ++_count;
    }
    The problem in your example is that the caller of readLock() already holds a lock on the mutex, tries to acquire the lock a second time, but then blocks because there is a waiting writer, which prevents it from releasing the initial lock.

    It seems it would be more appropriate to allow those readers that have a lock already to continue to acquire more read locks, and to only block those readers in readLock() that don't have a lock already.

    We'll discuss this internally.

    Cheers,

    Michi.

  4. #4
    jlawson71 is offline Registered User
    Name: Jeff Lawson
    Organization: Omniture
    Project: High voulme data transfer
    Join Date
    May 2008
    Posts
    2

    a little more explanation

    Looking at the source src/IceUtil/RWRecMutex.cpp

    The Read thread calls successfully through readLock(), leaving _count at 1.
    The Write thread calls writeLock and since _count isn't 0 it increments _waitingWriters and then waits on _writers.wait()
    The Read thread recursively calls readLock() and since _waitingWriters != 0 it waits on _readers.wait(). Deadlock!

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. Ice 3.4 Cpp RWRecMutex Class Deprecated
    By motta in forum Help Center
    Replies: 2
    Last Post: 03-12-2010, 05:39 AM
  2. bug ?
    By OrNot in forum Bug Reports
    Replies: 1
    Last Post: 12-03-2005, 03:58 AM
  3. Is this a bug?
    By GlacierX in forum Bug Reports
    Replies: 5
    Last Post: 05-17-2005, 09:54 AM
  4. RWRecMutex
    By xdm in forum Help Center
    Replies: 1
    Last Post: 03-22-2005, 02:51 AM
  5. much like a Bug !
    By damingyipai in forum Bug Reports
    Replies: 4
    Last Post: 04-04-2004, 12:41 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •