id,summary,reporter,owner,description,type,status,milestone,component,version,severity,resolution,keywords,cc 5516,Upgrade lock is not acquired when previous upgrade lock releases if another read lock is present,fred@…,viboes,"Thread 1 acquires a read lock on a shared mutex[[BR]] Thread 2 acquires an upgrade lock on the shared mutex[[BR]] Thread 3 tries to acquire an upgrade lock on the shared mutex, waits for it[[BR]] Thread 2 releases the lock At this point, I would expect thread 3 to acquire the lock, but it does not do it until thread 1 releases its read lock. This seems to be caused by the ""shared_mutex ::unlock_upgrade()"" method in thread/pthread/shared_mutex.hpp, that only calls ""release_waiters()"" if it is the last reader, ignoring that another upgrade lock might be waiting to take the lock. I suppose it could be fixed by maintaining a count of the number of threads waiting for an upgrade lock, and to signal the shared condition if this is non-zero. Here is an example program: {{{ #include #include class Test { public: void m1() { std::cout << ""m1 - Trying to take an shared lock"" << std::endl; boost::shared_lock lock(_mutex); std::cout << ""m1 - Took a shared lock"" << std::endl; sleep(5); std::cout << ""m1 - Released the lock"" << std::endl; } void m2() { sleep(1); std::cout << ""m2 - Trying to take an upgradable lock"" << std::endl; boost::upgrade_lock lock(_mutex); std::cout << ""m2 - Took an upgradable lock"" << std::endl; sleep(1); std::cout << ""m2 - Released an upgradable lock"" << std::endl; } void m3() { sleep(2); std::cout << ""m3 - Trying to take an upgradable lock"" << std::endl; boost::upgrade_lock lock(_mutex); std::cout << ""m3 - Took an upgradable lock"" << std::endl; std::cout << ""m3 - Releasing locks"" << std::endl; } void run() { boost::thread t1(&Test::m1, this); boost::thread t2(&Test::m2, this); m3(); t1.join(); t2.join(); } private: boost::shared_mutex _mutex; }; int main() { Test test; test.run(); return 0; } }}} Results: {{{ m1 - Trying to take an shared lock m1 - Took a shared lock m2 - Trying to take an upgradable lock m2 - Took an upgradable lock m3 - Trying to take an upgradable lock m2 - Released an upgradable lock m1 - Released the lock m3 - Took an upgradable lock m3 - Releasing locks }}} Expected: {{{ m1 - Trying to take an shared lock m1 - Took a shared lock m2 - Trying to take an upgradable lock m2 - Took an upgradable lock m3 - Trying to take an upgradable lock m2 - Released an upgradable lock m3 - Took an upgradable lock m3 - Releasing locks m1 - Released the lock }}} Tested in Boost 1.42, visually checked that Trunk would have the same behaviour. ",Patches,closed,Boost 1.50.0,thread,Boost 1.42.0,Problem,fixed,,viboes